Configuring OpenAPI
To expose your server actions as RESTful endpoints in your application, we recommend using zsa-openapi
. This ensures adherence to OpenAPI standards.
The functionality of zsa-openapi
is heavily inspired by and built upon the work done in trpc-openapi. We owe a lot of credit to trpc-openapi
for making this possible.
RESTful Endpoints
All server actions that you create can be exposed as RESTful endpoints using zsa-openapi
. To get started, run:
Next, define your desired server actions.
Now that you have your server actions, create an OpenAPI router and expose these actions as endpoints in your application. To do this in your Next.js application, create a route at /api/[[...openapi]]/route.ts
:
Ensure that your pathPrefix
matches the prefix to your /[[...openapi]]/route.ts
path.
You can now hit your server actions at the configured paths. Your server actions will take the path parameters defined in your router as input to the action.
Anything not defined as a path parameter but required in the server action input will be required in the query parameters or request body for that endpoint.
OpenAPI Documentation
zsa-openapi
allows you to take your RESTful API router and automatically generate valid, industry-standard OpenAPI documentation (OAS-compliant structure).
To do this in Next.js, start by creating an endpoint at /docs/page.ts
:
If you hit this endpoint, you should have access to your API documentation in OAS-compliant structure. Here is an example of the outputted structured docs: Swagger Editor.
Single endpoints
Additionally, if you only want to expose a single server action as an endpoint, you can use createRouteHandlersForAction
. This is good when you want to create adhoc route heandlers. For example:
Coerce
If you are trying to use a number value, you can use the coerce
modifier to automatically convert the string value to a number. For example:
Authentication
If you expose your server actions using createOpenApiServerActionRouter
or setupApiHandler
, then the NextRequest
object will automatically be available in your defined actions and procedures. For example:
In this example, the request object represents the incoming HTTP request. You can access various properties and methods of the request object, such as headers, to retrieve information from the request.
Response Metadata
When defining server actions using createServerAction
, you can access and modify the response metadata through the responseMeta
parameter in the action handler. The responseMeta
object allows you to customize the response headers and status code for the specific action.
Here's an example of how you can use responseMeta
:
In this example, the updatePost
action modifies the response metadata using the responseMeta
parameter. It sets the status code to 201
(Created) and adds a custom header x-custom-header
with the value "custom-value"
.
The ZSAResponseMeta
class provides the following properties:
headers: Headers
: Represents the headers of the response. You can use theset
,append
,delete
, and other methods of theHeaders
class to modify the response headers.statusCode: number
: Represents the status code of the response. By default, it is set to200
. You can assign a different status code as needed.
By modifying the responseMeta
object, you can customize the response metadata for each individual action, allowing you to have fine-grained control over the response behavior.
Using responseMeta
, you can tailor the response headers and status codes to match your API requirements and provide additional information or instructions to the clients consuming your API endpoints.
Extending Routers
The createOpenApiServerActionRouter
function allows you to extend routers by combining multiple routers together. This is useful when you have separate files for different resource types, such as posts and users, and want to combine their routes in the final route.ts
file.
Here's an example of how you can extend routers:
First we create a posts router:
Next we create a users router:
We then combine the two routers into a main router:
Finally, we export the main router:
In this example, we have separate files for posts and users routes. Each file creates its own router using createOpenApiServerActionRouter
. Then, in the final route.ts
file, we create a new router and use the extend
option to combine the postsRouter
and usersRouter
. This way, all the routes from both routers will be included in the final router.
Content Types
By default, zsa-openapi
will only accept requests with the application/json
content type for PUT and POST requests. If you need to accept other content types, you can specify them in the contentTypes
option:
zsa-openapi
will only allow PUT and POST requests through if the content-type
header matches one of the specified content types.
Error Handling
OpenAPI Error Status Codes
zsa-openapi
maps ZSA error codes to HTTP status codes. This can be useful when returning errors from an API endpoint:
Customizing Errors
You can customize the error responses returned by the OpenAPI router by providing a shapeError
function to the createRouteHandlers
function. This function takes an error object as input and returns an object with the desired error response properties.
Here's an example of how to customize the error responses:
It also works with createRouteHandlersForAction
:
You can even return your own custom error response:
Attributes
When defining OpenAPI actions using createOpenApiServerActionRouter
or setupApiHandler
, you can specify additional attributes to provide more information about the action. Here are the available attributes:
-
enabled?: boolean
: Determines whether the action is enabled or not. If set tofalse
, the action will be excluded from the generated OpenAPI documentation. Defaults totrue
. -
method: OpenApiMethod
: Specifies the HTTP method for the action. It can be one of the following values:"GET"
,"POST"
,"PATCH"
,"PUT"
, or"DELETE"
. This attribute is required. -
path: string
: Defines the URL path for the action. It should start with a forward slash (/
) and can include path parameters using curly braces (e.g.,"/posts/{postId}"
). This attribute is required. -
summary?: string
: Provides a brief summary or title for the action. It is used in the generated OpenAPI documentation. -
description?: string
: Describes the purpose or functionality of the action in more detail. It is used in the generated OpenAPI documentation. -
protect?: boolean
: Indicates whether the action requires authentication or authorization. If set totrue
, it implies that the action is protected and may require additional security measures. -
tags?: string[]
: Assigns tags or categories to the action. Tags are used to group related actions together in the generated OpenAPI documentation. -
headers?: (OpenAPIV3.ParameterBaseObject & { name: string; in?: "header" })[]
: Defines additional headers that are expected or required for the action. Each header is specified as an object with properties such asname
,description
,required
, etc. -
contentTypes?: OpenApiContentType[]
: Specifies the supported content types for the request body of the action. It can include values like"application/json"
,"multipart/form-data"
, etc. -
deprecated?: boolean
: Indicates whether the action is deprecated. If set totrue
, it implies that the action should be avoided or is no longer recommended for use. -
example?: { request?: Record<string, any>; response?: Record<string, any> }
: Provides example request and response payloads for the action. It can be used to illustrate the expected input and output of the action. -
responseHeaders?: Record<string, OpenAPIV3.HeaderObject | OpenAPIV3.ReferenceObject>
: Defines the headers that are included in the response of the action. Each header is specified as a key-value pair, where the key is the header name and the value is an object describing the header.
These attributes allow you to provide additional information and metadata about your OpenAPI actions, making the generated OpenAPI documentation more comprehensive and informative.
Example:
In this example, the createPost
action is defined with various attributes such as summary
, description
, tags
, protect
, headers
, contentTypes
, deprecated
, and example
. These attributes provide additional information about the action and are used to generate comprehensive OpenAPI documentation.
Default Attributes
The createOpenApiServerActionRouter
function also allows you to specify default OpenAPI attributes that will be applied to all actions in the router. This can be useful when you want to set common properties for all your actions.
Here's an example of how you can use defaults
:
In this example, we use the defaults
option to specify common properties for all actions in the router. We set the tags
to ["Posts"]
and define a required Authorization
header. These defaults will be applied to all actions in the router, so you don't have to specify them individually for each action.
Streaming
Below is an example to show how to use streaming in your server actions. TLDR is return your own Response : )