OpenAPI Support
DBOS CLI v0.6 adds the dbos-openapi generate
command that generates an OpenAPI 3.0.x definition file for a DBOS application.
This definition file can be used to automatically generate strongly typed client code to invoke DBOS application endpoints.
Generate OpenAPI Definition File
First, install @dbos-inc/dbos-openapi
as a development dependency in your project:
npm install --save-dev @dbos-inc/dbos-openapi
To generate a OpenAPI definition file for a DBOS application, run the following dbos-openapi
cli command:
npx dbos-openapi generate src/operations.ts
This command takes a single required argument - the path to the DBOS application's TypeScript entrypoint files.
For DBOS applications generated by npx @dbos-inc/create
, the entrypoint will be src/operations.ts
.
The dbos-openapi generate
command generates an OpenAPI definition file openapi.yaml
in the same folder as the entrypoint files.
This entrypoints
argument is slightly different from the runtimeConfig.entrypoints
config setting.
The dbos-openapi generate
argument references the TypeScript entrypoint files.
The runtimeConfig.entrypoints
setting references the JavaScript file generated from the TypeScript entrypoint files.
Generate Client Code From OpenAPI Definition
Multiple vendors provide OpenAPI client generators that will work with a generated OpenAPI declaration file. Each of these vendors have tools and documentation for generating client code for a variety of languages and runtimes. Some of these tools include:
- Microsoft Kiota
- OpenAPI Generator
- Swagger CodeGen and Online Editor
- openapi-typescript
- oazapfts
- OpenAPI TypeScript Codegen
We can't provide tutorials for all of these OpenAPI generator tools, but the Swagger Editor runs in the browser so is straightforward to use for a simple tutorial
First, you need to run npx dbos-openapi generate
against your DBOS application entrypoints as described above.
Note, the shop and payment backend applications from the E-Commerce demo app include generated OpenApi definition files if you want to try this without creating your own application.
Then, copy and paste the contents of the generated openapi.yaml
file into Swagger Editor.
Swagger Editor will validate the OpenAPI definitions and render a documentation page for the api.
Note, the Swagger Editor generated documentation includes tooling to trigger OpenAPI endpoints from directly in the web page.
This tooling will not work as the OpenAPI definition generated by dbos-openapi generate
does not include server URL information.
At the top of the Swagger Editor, there is a "Generate Client" dropdown menu. Select typescript-axios from the menu. This will download a zip file containing a TypeScript package with the code generated from the OpenAPI definition.
The typescript-axios
Swagger generator generates a full TypeScript package that supports npm install
and npm run build
.
Typically, you would incorporate the generated code into an existing client projects that needs to call into the DBOS project.
Here is some example code using the typescript-axios
Swagger generator and the OpenAPI definition for the E-Commerce Demo Shop DBOS application.
import { Configuration, DefaultApi } from "./index";
const config = new Configuration({
basePath: "http://localhost:8082"
});
const api = new DefaultApi(config);
async function main() {
const response = await api.getProducts();
for (const product of response.data) {
console.log(product.description);
}
}
main();
As mentioned earlier, the OpenAPI definition file generated for an application does not include server URL information.
The server basePath
must be included programmatically as in the code snippet above, regardless of the OpenAPI generator you choose to use.
Specify OpenAPI Security Scheme and Requirements
DBOS handlers (i.e. methods with @GetApi
or @PostApi
)
are mapped to OpenAPI path items.
Path item operations optionally include security requirements, which map to security schemes defined in the
components.securitySchemes
section of the OpenAPI definition file.
Some OpenAPI generators use this information to automatically manage user credentials in the generated client code.
Authentication in DBOS is done via the middleware function passed to @Authentication
.
Parsing the authentication logic to determine the OpenAPI security scheme information is not feasible.
To include authentication information in the OpenAPI file, declare the security scheme via the @OpenApiSecurityScheme
class decorator.
@Authentication(authMiddleware)
@OpenApiSecurityScheme({ type: 'http', scheme: 'bearer' })
export class Operations {
@GetApi("/post/:id")
@RequiredRoles(['user'])
static async getPost(ctx: TransactionContext, @ArgSource(ArgSources.URL) id: string) {
...
}
}
The @OpenApiSecurityScheme
decorator takes a single parameter, matching a supported security scheme
from the OpenAPI spec.
dbos-openapi generate
does not support the oauth2
OpenAPI security scheme at this time.
All handler methods on a class use the same @OpenApiSecurityScheme
in the generated OpenAPI definition,
except for methods that have no specified @RequiredRoles
.
DBOS does not check authentication or authorization info for methods without any required roles.
Methods without any required roles do not emit security requirements in the generated OpenAPI definition file.
@Authentication(authMiddleware)
@DefaultRequiredRoles(['user'])
@OpenApiSecurityScheme({ type: 'http', scheme: 'bearer' })
export class Operations {
@PostApi('/api/login')
@RequiredRoles([])
static async login(ctx: HandlerContext, username: string, password: string) {
...
}
}
This allows a developer to have authenticated and non authenticated methods within a single class. If you need to support different security schemes for different methods, those need to be divided into separate classes.