-
Notifications
You must be signed in to change notification settings - Fork 292
Add initial server docs #6742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add initial server docs #6742
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
2098d32
Add initial server docs
markcowl aab6a5f
Add emitter reference docs
markcowl ae638be
Adding changeset
markcowl ebad7de
Update generation of readme
markcowl 87cd208
Adding entries for static usage docs
markcowl 5d8c39a
Clean up reference
markcowl 99fa8fd
Update website deps
markcowl 1c7a3f9
Getting changes from build
markcowl df0fe85
Enable doc generation for js
markcowl abda121
Merge branch 'main' into add-server-emitter-docs
markcowl 2f119d5
Allow tspd to customize readme generation
markcowl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
.chronus/changes/add-server-emitter-docs-2025-2-27-18-48-27.md
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
changeKind: internal | ||
packages: | ||
- "@typespec/http-server-csharp" | ||
- "@typespec/http-server-js" | ||
--- | ||
|
||
Update to generate emitter docs |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
## Functionality and generated code | ||
|
||
The emitter generates a few major components: | ||
|
||
### Router | ||
|
||
The highest-level component that your code interacts with directly is the router implementation. | ||
`@typespec/http-server-js` generates a static router that you can bind to an implementation of an HTTP server. | ||
|
||
The router is generated in the `http/router.js` module within the output directory. Each service will have its own | ||
router implementation named after the service. For example, given a service namespace named `Todo`, the router module | ||
will export a function `createTodoRouter`. This function creates an instance of a router that dispatches methods within | ||
the `Todo` service. | ||
|
||
```ts | ||
import { createTodoRouter } from "../tsp-output/@typespec/http-server-js/http/router.js"; | ||
|
||
const router = createTodoRouter(users, todoItems, attachments); | ||
``` | ||
|
||
As arguments, the `createTodoRouter` function expects implementations of the underlying service interfaces. These | ||
interfaces are explained further in the next section. | ||
|
||
Once the router is created, it is bound to an instance of the HTTP server. The router's `dispatch` method implements the | ||
Node.js event handler signature for the `request` event on a Node.js HTTP server. | ||
|
||
```ts | ||
const server = http.createServer(); | ||
|
||
server.on("request", router.dispatch); | ||
|
||
server.listen(8080, () => { | ||
console.log("Server listening on http://localhost:8080"); | ||
}); | ||
``` | ||
|
||
Alternatively, the router can be used with Express.js instead of the Node.js HTTP server directly. If the `express` | ||
feature is enabled in the emitter options, the router will expose an `expressMiddleware` property that implements the | ||
Express.js middleware interface. | ||
|
||
```ts | ||
import express from "express"; | ||
|
||
const app = express(); | ||
|
||
app.use(router.expressMiddleware); | ||
|
||
app.listen(8080, () => { | ||
console.log("Server listening on http://localhost:8080"); | ||
}); | ||
``` | ||
|
||
### Service interfaces | ||
|
||
The emitter generates interfaces for each collection of service methods that exists in the service namespace. | ||
Implementations of these interfaces are required to instantiate the router. When the router processes an HTTP request, | ||
it will call the appropriate method on the service implementation after determining the route and method. | ||
|
||
For example, given the following TypeSpec namespace `Users` within the `Todo` service: | ||
|
||
```tsp | ||
namespace Users { | ||
@route("/users") | ||
@post | ||
op create( | ||
user: User, | ||
): WithStandardErrors<UserCreatedResponse | UserExistsResponse | InvalidUserResponse>; | ||
} | ||
``` | ||
|
||
The emitter will generate a corresponding interface `Users` within the module `models/all/todo/index.js` in the output | ||
directory. | ||
|
||
```ts | ||
/** An interface representing the operations defined in the 'Todo.Users' namespace. */ | ||
export interface Users<Context = unknown> { | ||
create( | ||
ctx: Context, | ||
user: User, | ||
): Promise< | ||
| UserCreatedResponse | ||
| UserExistsResponse | ||
| InvalidUserResponse | ||
| Standard4XxResponse | ||
| Standard5XxResponse | ||
>; | ||
} | ||
``` | ||
|
||
An object implementing this `Users` interface must be passed to the router when it is created. The `Context` type | ||
parameter represents the underlying protocol or framework-specific context that the service implementation may inspect. | ||
If you need to access the HTTP request or response objects directly in the implementation of the service methods, you | ||
must use the `HttpContext` type as the `Context` argument when implementing the service interface. Otherwise, it is safe | ||
to use the default `unknown` argument. | ||
|
||
```ts | ||
import { HttpContext } from "../tsp-output/@typespec/http-server-js/helpers/router.js"; | ||
import { Users } from "../tsp-output/@typespec/http-server-js/models/all/todo/index.js"; | ||
|
||
export const users: Users<HttpContext> = { | ||
async create(ctx, user) { | ||
// Implementation | ||
}, | ||
}; | ||
``` | ||
|
||
### Models | ||
|
||
The emitter generates TypeScript interfaces that represent the model types used in the service operations. This allows | ||
the service implementation to interact with the data structures carried over the HTTP protocol in a type-safe manner. | ||
|
||
### Operation functions | ||
|
||
While your code should never need to interact with these functions directly, the emitter generates a function per HTTP | ||
operation that handles the parsing and validation of the request contents. This allows the service implementation to be | ||
written in terms of ordinary TypeScript types and values rather than raw HTTP request and response objects. In general: | ||
|
||
- The Node.js HTTP server or Express.js application (your code) calls the router (generated code), which determines | ||
which service operation function (generated code) to call based on the route, method, and other HTTP metadata in the | ||
case of shared routes. | ||
- The operation function (generated code) deserializes the request body, query parameters, and headers into TypeScript | ||
types, and may perform request validation. | ||
- The operation function (generated code) calls the service implementation (your code) with the deserialized request | ||
data. | ||
- The service implementation (your code) returns a result or throws an error. | ||
- The operation function (generated code) responds to the HTTP request on your behalf, converting the result or error | ||
into HTTP response data. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
:warning: **This package is highly experimental and may be subject to breaking changes and bugs.** Please expect that your code may need to be updated as this package evolves, and please report any issues you encounter. |
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
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
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
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
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.