Docs: Introduce new OpenAPI integration

This commit is contained in:
fuma-nama
2024-08-08 15:55:31 +08:00
parent 6c4296042c
commit 971817c60c
6 changed files with 412 additions and 262 deletions
+28
View File
@@ -0,0 +1,28 @@
---
'fumadocs-openapi': major
---
**Migrate to React Server Component**
The API reference page is now a server component.
The MDX generator will only generate a small MDX file, and the rest will be handled by our `APIPage` component.
```mdx
---
title: Delete Api
full: true
method: POST
route: /v1/apis.deleteApi
---
<APIPage
operations={[{ path: '/v1/apis.deleteApi', method: 'post' }]}
hasHead={false}
/>
```
- Markdown/MDX content is still supported, but will be processed in the server component (during runtime) instead.
- Your Remark/Rehype plugins (e.g. Rehype Code) configured in Fumadocs MDX or other source providers, will **not** be shared. Fumadocs OpenAPI uses a separate MDX processor instance.
- `APIPage` component will fetch the OpenAPI Schema when being rendered. **On Vercel**, if it relies on the file system, ensure the page **will not** be re-rendered after build.
Please refer to documentation for the new usage.
@@ -1,262 +0,0 @@
---
title: OpenAPI Generator
description: Generating docs for OpenAPI schema
---
## Usage
Install the required packages.
```package-install
fumadocs-openapi
```
### Generate Styles
The interactive UI of OpenAPI integration is styled with Tailwind CSS, it doesn't include a pre-built stylesheet by default.
You must use it in conjunction with the [official Tailwind CSS plugin](/docs/ui/theme#docsui-plugin).
Add the package to `content` under your Tailwind CSS configuration.
```js title="tailwind.config.js"
import { createPreset } from 'fumadocs-ui/tailwind-plugin';
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./node_modules/fumadocs-ui/dist/**/*.js',
'./node_modules/fumadocs-openapi/dist/**/*.js',
],
presets: [createPreset()],
};
```
### Generate Files
Create a script:
```js title="scripts/generate-docs.mjs"
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'], // the OpenAPI schemas
output: './content/docs',
});
```
> Only OpenAPI 3.0 is supported.
>
> It doesn't allow JSON schema specific keywords like `const`, as [they are unsupported](https://swagger.io/docs/specification/data-models/keywords)
Generate docs with the script:
```bash
node ./scripts/generate-docs.mjs
```
Fumadocs OpenAPI generates MDX content directly, you can use a formatter (e.g. Prettier) to format the output files.
### Generate Page Tree
You can add the `attachFile` to decorate the page tree with Source API.
It adds a badge to each page item.
```ts title="source.ts"
import { createMDXSource, defaultSchemas } from 'fumadocs-mdx';
import { z } from 'zod';
import { loader } from 'fumadocs-core/source';
import { attachFile } from 'fumadocs-openapi/source';
const frontmatter = defaultSchemas.frontmatter.extend({
method: z.string().optional(),
});
export const utils = loader({
source: createMDXSource(map, {
schema: {
frontmatter,
},
}),
pageTree: {
attachFile,
},
// other props
});
```
## Features
The official OpenAPI integration supports:
- Basic API endpoint information
- Interactive API playground
- Example code to send request (in different programming languages)
- Response samples and TypeScript definitions
- Request parameters and body generated from schemas
### Demo
[View demo](/docs/ui/museum).
## Options
You can also pass options to the `generateFiles` function.
### Input
An array of input files (path), wildcard allowed.
### Output
Path to the output directory.
### Per
Customise how the page is generated, default to `file`.
| mode | Generate a page for |
| --------- | ----------------------------------- |
| tag | each tag |
| file | each schema |
| operation | each operation (method of endpoint) |
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
per: 'tag',
});
```
### Group By Folder
In `operation` mode, you can group operations with folders.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
per: 'operation',
groupByFolder: true,
});
```
### Name
A function that controls the output path of files.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
name: (type, file) => {
return; // filename
},
});
```
### Imports
The imports on the top of MDX files.
When not specified, it imports the required components from the package itself.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
imports: [
{
names: ['Component1', 'Component2'],
from: '@/components/ui/api',
},
],
});
```
### Frontmatter
Customise the frontmatter of MDX files.
By default, it includes:
| property | description |
| ------------- | ------------------------------------------------ |
| `title` | Page title |
| `description` | Page description |
| `full` | Always true, added for Fumadocs UI |
| `method` | Available method of operation (`operation` mode) |
| `route` | Route of operation (`operation` mode) |
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
frontmatter: (title, description) => ({
myProperty: 'hello',
}),
});
```
### Generate Code Samples
Generate custom code samples for each API endpoint.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
generateCodeSamples(endpoint) {
return [
{
lang: 'js',
label: 'JavaScript SDK',
source: "console.log('hello')",
},
];
},
});
```
In addition, you can also specify code samples via OpenAPI schema.
```yaml
paths:
/plants:
get:
x-codeSamples:
- lang: js
label: JavaScript SDK
source: |
const planter = require('planter');
planter.list({ unwatered: true });
```
### Renderer
Customise how components are generated.
```ts
import { generateFiles, createElement } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
renderer: {
Root(props, child) {
return createElement(
'Root',
props,
'<div className="bg-fd-secondary p-4 rounded-lg">Demo Only</div>',
...child,
);
},
},
});
```
@@ -0,0 +1,48 @@
---
title: Advanced
description: Advanced topics of Fumadocs OpenAPI
---
## How It Works?
Fumadocs OpenAPI has two parts:
### File Generator
It generates the MDX page with correct frontmatter, so you don't have to manually create a MDX file for each endpoint/operation.
### OpenAPI Server
It renders the API page, a server component.
The schema passed to server will also be fetched dynamically on server.
### Markdown
Markdown/MDX content is rendered in the server component (during runtime) using `@mdx-js/mdx`.
Your Remark/Rehype plugins (e.g. Rehype Code) configured in Fumadocs MDX or other source providers, will **not** be shared.
Fumadocs OpenAPI uses a separate MDX processor instance.
## Use API Page
To use the `APIPage` component in your MDX files directly:
```mdx
---
title: Delete Api
full: true
method: POST
route: /v1/apis.deleteApi
---
<APIPage
operations={[{ path: '/v1/apis.deleteApi', method: 'post' }]}
hasHead={false}
/>
```
| Prop | Description |
| ------------ | ----------------------------------------- |
| `operations` | Operations (API endpoints) to be rendered |
| `hasHead` | Enable to render the heading of operation |
@@ -0,0 +1,201 @@
---
title: Configurations
description: Customise Fumadocs OpenAPI
---
## File Generator
Pass options to the `generateFiles` function.
### Input
An array of input files (path), wildcard allowed.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./unkey.json'],
});
```
### Output
Path to the output directory.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
output: '/content/docs',
});
```
### Per
Customise how the page is generated, default to `file`.
| mode | Generate a page for |
| --------- | ----------------------------------- |
| tag | each tag |
| file | each schema |
| operation | each operation (method of endpoint) |
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
per: 'tag',
});
```
### Group By
In `operation` mode, you can group output files with folders.
| Group by | Description |
| -------- | ------------------------------------------------------------ |
| tag | `{tag}/{page}.mdx` (Each operation can only contain `1` tag) |
| route | `{api-endpoint}/{page}.mdx` |
| none | `{page}.mdx` (default) |
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
per: 'operation',
groupBy: 'tag',
});
```
### Name
A function that controls the output path of files.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
name: (type, file) => {
return; // filename
},
});
```
### Imports
Add additional imports on the top of MDX files.
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
imports: [
{
names: ['Component1', 'Component2'],
from: '@/components/ui/api',
},
],
});
```
### Frontmatter
Customise the frontmatter of MDX files.
By default, it includes:
| property | description |
| ------------- | ------------------------------------------------ |
| `title` | Page title |
| `description` | Page description |
| `full` | Always true, added for Fumadocs UI |
| `method` | Available method of operation (`operation` mode) |
| `route` | Route of operation (`operation` mode) |
```ts
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./petstore.yaml'],
output: './content/docs',
frontmatter: (title, description) => ({
myProperty: 'hello',
}),
});
```
## OpenAPI Server
The server to render pages.
### Input
The Input OpenAPI schema.
It can be the schema content (as JavaScript Object), a file path, or URL.
The schema is dynamically fetched when the `APIPage` component renders.
```ts
import { createOpenAPI } from 'fumadocs-openapi/server';
export const openapi = createOpenAPI({
documentOrPath: './unkey.json',
});
```
<Callout type='warn' title='For Vercel'>
If it relies on the file system, ensure the page **will not** be re-rendered after build.
</Callout>
### Generate Code Samples
Generate custom code samples for each API endpoint.
```ts
import { createOpenAPI } from 'fumadocs-openapi/server';
export const openapi = createOpenAPI({
generateCodeSamples(endpoint) {
return [
{
lang: 'js',
label: 'JavaScript SDK',
source: "console.log('hello')",
},
];
},
});
```
In addition, you can also specify code samples via OpenAPI schema.
```yaml
paths:
/plants:
get:
x-codeSamples:
- lang: js
label: JavaScript SDK
source: |
const planter = require('planter');
planter.list({ unwatered: true });
```
### Renderer
Customise components in the page.
```ts
import { createOpenAPI } from 'fumadocs-openapi/server';
export const openapi = createOpenAPI({
renderer: {
Root(props, child) {
// your own (server) component
},
},
});
```
@@ -0,0 +1,132 @@
---
title: OpenAPI
description: Generating docs for OpenAPI schema
---
## Usage
Install the required packages.
```package-install
fumadocs-openapi
```
### Generate Styles
The interactive UI of OpenAPI integration is styled with Tailwind CSS, it doesn't include a pre-built stylesheet by default.
You must use it in conjunction with the [official Tailwind CSS plugin](/docs/ui/theme#docsui-plugin).
Add the package to `content` under your Tailwind CSS configuration.
```js title="tailwind.config.js"
import { createPreset } from 'fumadocs-ui/tailwind-plugin';
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./node_modules/fumadocs-ui/dist/**/*.js',
'./node_modules/fumadocs-openapi/dist/**/*.js',
],
presets: [createPreset()],
};
```
### Configure Pages
Create an OpenAPI instance on the server. Fumadocs OpenAPI renders the pages on server-side.
```ts title="source.ts"
import { createOpenAPI } from 'fumadocs-openapi/server';
export const openapi = createOpenAPI({
// Your OpenAPI Schema (content, url, or path)
// relative to `cwd`
documentOrPath: './unkey.json',
});
```
Add `APIPage` to your MDX Components, so that you can use it in MDX files.
```tsx title="mdx-components.tsx"
import type { MDXComponents } from 'mdx/types';
import defaultComponents from 'fumadocs-ui/mdx';
import { openapi } from '@/app/source';
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...defaultComponents,
...components,
APIPage: openapi.APIPage,
};
}
```
> It is a React Server Component.
### Generate Files
You can generate MDX files directly from your OpenAPI schema.
Create a script:
```js title="scripts/generate-docs.mjs"
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./unkey.json'], // the OpenAPI schemas
output: './content/docs',
});
```
> Only OpenAPI 3.0 is supported.
>
> It doesn't allow JSON schema specific keywords like `const`, as [they are unsupported](https://swagger.io/docs/specification/data-models/keywords)
Generate docs with the script:
```bash
node ./scripts/generate-docs.mjs
```
### Generate Page Tree
You can add the `attachFile` to decorate the page tree with Source API.
It adds a badge to each page item.
```ts title="source.ts"
import { createMDXSource, defaultSchemas } from 'fumadocs-mdx';
import { z } from 'zod';
import { loader } from 'fumadocs-core/source';
import { attachFile } from 'fumadocs-openapi/server';
const frontmatter = defaultSchemas.frontmatter.extend({
method: z.string().optional(),
});
export const utils = loader({
source: createMDXSource(map, {
schema: {
frontmatter,
},
}),
pageTree: {
attachFile,
},
// other props
});
```
## Features
The official OpenAPI integration supports:
- Basic API endpoint information
- Interactive API playground
- Example code to send request (in different programming languages)
- Response samples and TypeScript definitions
- Request parameters and body generated from schemas
### Demo
[View demo](/docs/ui/museum).
@@ -0,0 +1,3 @@
{
"pages": ["configurations", "..."]
}