Skip to main content

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.

info

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:

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.

info

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.

info

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();
info

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.

info

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.