Introduce HttpServer (and begin deprecating HttpPlugin)#433
Merged
Conversation
heyitsaamir
force-pushed
the
aamirj/simlifyHttp
branch
from
January 16, 2026 07:09
f07e077 to
d9a529e
Compare
heyitsaamir
force-pushed
the
httpAdapter
branch
3 times, most recently
from
January 17, 2026 07:13
6601a42 to
7e55c15
Compare
lilyydu
reviewed
Jan 21, 2026
heyitsaamir
commented
Jan 22, 2026
rido-min
reviewed
Jan 22, 2026
rido-min
reviewed
Jan 22, 2026
heyitsaamir
force-pushed
the
aamirj/simlifyHttp
branch
from
January 23, 2026 18:55
2fa2032 to
4590e50
Compare
heyitsaamir
force-pushed
the
httpAdapter
branch
5 times, most recently
from
January 24, 2026 09:20
4c1ca04 to
5422e29
Compare
heyitsaamir
commented
Jan 24, 2026
heyitsaamir
left a comment
Collaborator
Author
There was a problem hiding this comment.
Questions:
- Should we remove app.initialize()? I feel like we could remove it, but i like having it because it could give us a way to initialize things asynchronously if needed.
- Ideally we should not be shipping with a server at all -- If we want to do
serve(new App())whereservecomes from anexpressspecific package, that'll lead to a pretty big breaking change for all our docs for our simplest use-cases. For this reason, I think we should leaveapp.startthe way it is, and for v3 consider removing.start.
Merged
heyitsaamir
force-pushed
the
httpAdapter
branch
3 times, most recently
from
January 26, 2026 17:04
4ec6679 to
95d91e9
Compare
corinagum
pushed a commit
that referenced
this pull request
Feb 12, 2026
This PR upgrades our systems from express v4 to express v5. The changes applicable to us are fairly minimal #### PR Dependency Tree * **PR #424** * **PR #433** * **PR #442** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
aacebo
reviewed
Mar 10, 2026
aacebo
reviewed
Mar 10, 2026
aacebo
reviewed
Mar 10, 2026
aacebo
reviewed
Mar 10, 2026
heyitsaamir
added a commit
that referenced
this pull request
Mar 11, 2026
This PR upgrades our systems from express v4 to express v5. The changes applicable to us are fairly minimal #### PR Dependency Tree * **PR #424** * **PR #433** * **PR #442** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir
force-pushed
the
httpAdapter
branch
from
March 11, 2026 06:35
bf5ef7e to
23c12d5
Compare
heyitsaamir
added a commit
that referenced
this pull request
Mar 12, 2026
This PR upgrades our systems from express v4 to express v5. The changes applicable to us are fairly minimal #### PR Dependency Tree * **PR #424** * **PR #433** * **PR #442** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir
force-pushed
the
httpAdapter
branch
from
March 12, 2026 05:57
23c12d5 to
6fee68d
Compare
This PR upgrades our systems from express v4 to express v5. The changes applicable to us are fairly minimal * **PR #424** * **PR #433** * **PR #442** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
- Remove IRequestHelpers/IRouteConfig callback pattern — handlers are
now pure functions: ({ body, headers }) → { status, body }
- Remove initialize() from adapter interface (all were no-ops)
- Rename to registerRoute(method, path, handler) with typed HttpMethod
- Type request/response bodies as unknown instead of any
- No breaking changes to ExpressAdapter or HttpPlugin public APIs
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Rename the interface and app option to better reflect that this is a server-side HTTP adapter: IHttpAdapter → IHttpServerAdapter, httpAdapter → httpServerAdapter.
Restify was the default HTTP server used by the Bot Framework JS SDK. This example shows how to use it with teams.ts via IHttpServerAdapter.
…lugins IHttpServer was unnecessary indirection — every plugin only used httpServer.adapter. Now plugins inject the adapter directly via @HttpServerAdapter() decorator. Also scopes express.json() and cors() to only the routes that need them instead of applying globally. Co-Authored-By: Claude Opus 4.6 <[email protected]>
…s, add backward compat JSON parsing - Stop HTTP server in app.stop() and call stop() if start() fails - Update deprecation messages to reference httpServerAdapter option - Soften deprecation timeline to "future version" - Add express.json() backward compat in deprecated HttpPlugin Co-Authored-By: Claude Opus 4.6 <[email protected]>
heyitsaamir
force-pushed
the
httpAdapter
branch
from
March 16, 2026 19:44
33218c2 to
7e6df6f
Compare
singhk97
approved these changes
Mar 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR, we introduce a new object called HttpServer and begin to deprecate HttpPlugin.
Main changes
HttpServerinternal class. It accepts anIHttpServerAdapterwhich is the server implementation.IHttpServerAdapterWhy:
HTTP is a core part of our sdk. Our App object uses HTTP to set up a server, perform auth validations, and pipe the request to the handlers that are attached, and then return the response. Key part is that Http is a core part of App, not a plugin, since core functionality is dependent on it.
Even inside the App object, we were doing special casing for this Http"Plugin" whereas it should never have really been a plugin to begin with. By making it a plugin, we were exposing many non-plugin essential things to the plugin system in general.
So what should it have been? Well, HTTP Plugin had these responsibilities
So, we introduce a new object called
HttpServerwhose responsibilities are essentially that ^. This object is not a plugin, but an object that's created by App itself.Customization
Now this idealogical shift doesn't really warrant us doing this refactor, but we started seeing requests from folks who wanted to hook Teams functionality into existing servers, or replace the underlying server infra with a non-express server. Our recommendation was to rebuild a new HttpPlugin. But rebuilding this plugin is not simple (since we don't really document it anywhere, and didn't expect folks to build their own).
So
HttpServerexposes anIHttpServerAdapterconcept. To build the adapter, one simply needs to build out a handler for extracting request data, and a handler for responses. This means that you can build simple custom adapters for your own existing servers. (And if you don't pass one in, we'll build a default express one.) Examples of servers are in the http-adapters folder under examples/.Adapter Interface
The
IHttpServerAdapterinterface adapters need to implement:Handlers are pure functions —
({ body, headers }) → { status, body }. No framework-specific request/response objects leak through the abstraction.Why
registerRoute?Some adapter patterns have the adapter own routing internally and just receive a single callback. But our SDK creates routes dynamically —
app.function('myFunc')registers/api/functions/myFuncat runtime, in addition to the core/api/messagesendpoint. The adapter needs aregisterRoutemethod so that bothHttpServerandapp.function()can tell it what paths to listen on.Optional methods
start/stopare optional — serverless adapters (Vercel, Lambda) don't need them.serveStaticis optional — only needed for tab hosting.HttpMethodis currently just'POST'(the only method the Teams protocol uses). It may expand to a union if needed.Backward Compat
We've updated
HttpPluginto basically useHttpServerwith anExpressAdapterinternally for backward compat. I don't think this should lead to any breaking changes (even if someone passes in their ownHttpPlugin). (Tested BotBuilderPlugin, from examples, and it worked without any changes).However, it should be noted that I marked HttpPlugin as deprecated in this PR, so it should be discouraged going forward, and after the next few versions, it'll be removed.
Testing
I tested by running the following examples:
skip-test-verification (added manifest for tabs)
PR Dependency Tree
PR Dependency Tree
This tree was auto-generated by Charcoal