Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 136 additions & 2 deletions docusaurus/docs/cms/api/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tags:

Strapi provides a command-line tool to generate <ExternalLink to="https://www.openapis.org/" text="OpenAPI"/> specifications for your applications.

The CLI tool automatically creates comprehensive API documentation that describes all available endpoints, parameters, and response formats in your Strapi application's Content API. Among the possible use cases, the generated specification can then be easily integrated into documentation tools like <ExternalLink to="https://swagger.io/tools/swagger-ui/" text="Swagger UI "/>.
The CLI tool automatically creates comprehensive API documentation that describes all available endpoints, parameters, and response formats in your Strapi application's Content API. Among the possible use cases, the generated specification can then be integrated into documentation tools like <ExternalLink to="https://swagger.io/tools/swagger-ui/" text="Swagger UI "/>.

:::callout 🚧 Experimental feature
The OpenAPI generation feature is currently experimental. Its behavior and output might change in future releases without following semantic versioning. For additional information and context, please refer to the <ExternalLink text="Strapi Contributor Docs " to="https://contributor.strapi.io/openapi" />.
Expand Down Expand Up @@ -51,7 +51,7 @@ npm run strapi openapi generate
</TabItem>
</Tabs>

You can also path an optional `--output` argument to specify the path and filename, as in the following example:
You can also pass an optional `--output` argument to specify the path and filename, as in the following example:

<Tabs groupId="yarn-npm">
<TabItem value="yarn" label="Yarn">
Expand Down Expand Up @@ -154,8 +154,142 @@ The generated OpenAPI specification includes all available API endpoints in your
- File upload endpoints for media handling
- Plugin endpoints from installed plugins

## Serving the specification over HTTP

Strapi can serve the generated OpenAPI specification as a live HTTP endpoint. Serving specifications over HTTP removes the need to regenerate a static file after each content-type change. Both the Content API and Admin API specifications can be served independently.

Both endpoints use `access: 'disabled'` by default and are not registered. Set `access` on 1 or both endpoints in the [server configuration](/cms/configurations/server) file to expose them.

### Configuration

Add an `openapi` key to the `server` configuration:

<Tabs groupId="js-ts">
<TabItem value="js" label="JavaScript">

```js title="/config/server.js"
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
// highlight-start
openapi: {
'content-api': {
access: 'public',
route: {
path: '/openapi.json',
},
cache: {
enabled: true,
maxAgeMs: 60000,
filePath: '.strapi/openapi/content-api.json',
},
},
admin: {
access: 'authenticated',
route: {
path: '/openapi.json',
},
cache: {
enabled: true,
maxAgeMs: 60000,
filePath: '.strapi/openapi/admin.json',
},
},
},
// highlight-end
});
```

</TabItem>

<TabItem value="ts" label="TypeScript">

```ts title="/config/server.ts"
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
// highlight-start
openapi: {
'content-api': {
access: 'public',
route: {
path: '/openapi.json',
},
cache: {
enabled: true,
maxAgeMs: 60000,
filePath: '.strapi/openapi/content-api.json',
},
},
admin: {
access: 'authenticated',
route: {
path: '/openapi.json',
},
cache: {
enabled: true,
maxAgeMs: 60000,
filePath: '.strapi/openapi/admin.json',
},
},
},
// highlight-end
});
```

</TabItem>
</Tabs>

The `content-api` endpoint is served under the REST API prefix (`/api` by default). The full URL is `http://localhost:1337/api/openapi.json`. The `admin` endpoint is served under the admin path (`/admin` by default). The full URL is `http://localhost:1337/admin/openapi.json`.

:::caution
Both endpoints must resolve to different full paths. If the `content-api` and `admin` endpoints resolve to the same URL, Strapi throws an error at startup.
:::

### Available options

Each endpoint (`content-api` and `admin`) accepts the following options:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `access` | String | `'disabled'` | Controls whether the endpoint is registered and how it is protected. See [Access control](#access-control) for accepted values per endpoint. |
| `route.path` | String | `'/openapi.json'` | Path where the specification is served. Appended to the endpoint prefix (`/api` for `content-api`, `/admin` for `admin`). |
| `cache.enabled` | Boolean | `true` | Enables file-based caching of the generated specification. |
| `cache.maxAgeMs` | Number | `60000` | Maximum age of the cache file in milliseconds before regeneration. |
| `cache.filePath` | String | `'.strapi/openapi/<type>.json'` | File path for the cache file. Relative paths are resolved from the application root. |

### Access control

The `access` option controls whether each endpoint is registered and how it is protected. Each endpoint supports different values:

**Content API** (`content-api`):

| Value | Behavior |
|-------|----------|
| `'disabled'` (default) | The endpoint is not registered. |
| `'public'` | The endpoint is registered without authentication. Anyone can fetch the specification. |

**Admin** (`admin`):

| Value | Behavior |
|-------|----------|
| `'disabled'` (default) | The endpoint is not registered. |
| `'authenticated'` | The endpoint requires an authenticated admin session. Any authenticated admin user can access the specification. |

:::note
Role-based access control for OpenAPI endpoints is not supported yet. The admin endpoint uses the `admin::isAuthenticatedAdmin` policy and does not filter by admin role or permission.
:::

:::tip
The Content API endpoint is always public when `access` is `'public'`. If you do not want to expose the specification without authentication, leave `content-api.access` at `'disabled'` and use the CLI to generate a static file instead.
:::

## Integrating with Swagger UI

:::tip
If you [registered an HTTP endpoint](#serving-the-specification-over-http), you can point Swagger UI directly at the live URL (e.g., `http://localhost:1337/api/openapi.json`) instead of generating a static file. Skip step 1 below and use the endpoint URL as the `url` value in step 3.
:::

With the following steps you can quickly generate a [Swagger UI](https://swagger.io/)-compatible page:

1. Generate a specification:
Expand Down
34 changes: 30 additions & 4 deletions docusaurus/docs/cms/configurations/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tags:
- configuration
- cron job
- host
- openapi
- port
---

Expand All @@ -26,7 +27,7 @@ Changes to the `server.js` file require rebuilding the admin panel. After saving

## Available options

The `./config/server.js` file can include the following parameters:
The `/config/server.js` file can include the following parameters:

<!-- TODO: add admin jwt config option -->
<!-- TODO: sort options alphabetically in the table below -->
Expand Down Expand Up @@ -54,8 +55,19 @@ The `./config/server.js` file can include the following parameters:
| `http.serverOptions` | Options passed to http `createServer` | <ExternalLink to="https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener" text="http.serverOptions"/> | {} |
| `transfer.remote.enabled` | Toggle the ability to use the [transfer feature](/cms/data-management/transfer) | boolean | `true` |
| `transfer.remote.assetIdleTimeoutMs` | Timeout in milliseconds without incoming data before an asset stream is considered stalled when using `strapi transfer --from` to pull from a remote instance. Increase this value when transferring large files or when working on slow connections. | integer | <!-- TODO: confirm default value from strapi/strapi codebase --> |
| `logger.startup.enabled` | Toggle the the startup message in the terminal | boolean | `true` |
| `logger.startup.enabled` | Toggle the startup message in the terminal | boolean | `true` |
| `logger.updates.enabled` | Toggle the notification message about updating strapi in the terminal | boolean | `true` |
| `openapi` | [OpenAPI](/cms/api/openapi) endpoint configuration. Both endpoints use `access: 'disabled'` by default and are not registered. | object | |
| `openapi['content-api'].access` | Access mode: `disabled` (not registered) or `public` (no authentication). | string | `disabled` |
| `openapi['content-api'].route.path` | Subpath for the Content API endpoint, resolved under the [REST API prefix](/cms/configurations/api). | string | `/openapi.json` |
| `openapi['content-api'].cache.enabled` | Enable file-based caching of the generated specification. | boolean | `true` |
| `openapi['content-api'].cache.maxAgeMs` | Cache validity in milliseconds. | integer | `60000` |
| `openapi['content-api'].cache.filePath` | File path for the cached specification. Relative paths resolve from the application root. | string | `.strapi/openapi/content-api.json` |
| `openapi.admin.access` | Access mode: `disabled` (not registered) or `authenticated` (requires admin session). | string | `disabled` |
| `openapi.admin.route.path` | Subpath for the Admin endpoint, resolved under the [admin path](/cms/configurations/admin-panel). | string | `/openapi.json` |
| `openapi.admin.cache.enabled` | Enable file-based caching of the generated specification. | boolean | `true` |
| `openapi.admin.cache.maxAgeMs` | Cache validity in milliseconds. | integer | `60000` |
| `openapi.admin.cache.filePath` | File path for the cached specification. Relative paths resolve from the application root. | string | `.strapi/openapi/admin.json` |

:::note
There is no Strapi-specific keep alive configuration option, because Strapi uses Node's default one for incoming HTTP requests, keeping connections alive by default.
Expand All @@ -73,12 +85,12 @@ axios.get('https://example.com', { httpsAgent: agent });
:::

:::tip
Strapi exposes a dedicated health check route to make uptime probes straightforward. Any request to `/_health` returns an empty response with a `204` status and a `strapi: You are so French!` response header, which is suitable for load balancers or monitoring tools that only need a simple liveness indicator.
Strapi exposes a dedicated health check route for uptime probes. Any request to `/_health` returns an empty response with a `204` status and a `strapi: You are so French!` response header, which is suitable for load balancers or monitoring tools that only need a simple liveness indicator.
:::

## Configurations

The `./config/server.js` minimal configuration requires the `host` and `port` parameters for development. Additional parameters can be included for a full configuration.
The `/config/server.js` minimal configuration requires the `host` and `port` parameters for development. Additional parameters can be included for a full configuration.

:::note
[Environmental configurations](/cms/configurations/environment.md) (i.e. using the `env()` helper) do not need to contain all the values so long as they exist in the default `./config/server.js`.
Expand Down Expand Up @@ -154,6 +166,13 @@ module.exports = ({ env }) => ({
enabled: false,
},
},
// highlight-start
openapi: {
'content-api': {
access: 'public',
},
},
// highlight-end
});
```

Expand Down Expand Up @@ -188,6 +207,13 @@ export default ({ env }) => ({
enabled: false,
},
},
// highlight-start
openapi: {
'content-api': {
access: 'public',
},
},
// highlight-end
});
```

Expand Down
Loading