29
loading...
This website collects cookies to deliver better user experience
As usual, this article isn't meant as an in-depth guide, but as a documentation of the what, why, and how of certain architectural choices. If you're trying to achieve the same thing and need help, leave a comment!
/open-api.json
).const options = {
definition: {
openapi: "3.1.0",
info: {
title: "BobaBoard's API documentation.",
version: "0.0.1",
// Note: indenting the description will cause the markdown not to format correctly.
description: `
# Intro
Welcome to the BobaBoard's backend API. This is still a WIP.
# Example Section
This is just to test that sections work. It will be written better later.
`,
contact: {
name: "Ms. Boba",
url: "https://www.bobaboard.com",
email: "[email protected]",
},
},
servers: [
{
url: "http://localhost:4200/",
description: "Development server",
},
],
// These are used to group endpoints in the sidebar
tags: [
{
name: "/posts/",
description: "All APIs related to the /posts/ endpoints.",
},
{
name: "/boards/",
description: "All APIs related to the /boards/ endpoints.",
},
{
name: "todo",
description: "APIs whose documentation still needs work.",
},
],
// Special Redoc section to control how tags display in the sidebar.
"x-tagGroups": [
{
name: "general",
tags: ["/posts/", "/boards/"],
},
],
},
// Which paths to parse the API specs from.
apis: ["./types/open-api/*.yaml", "./server/*/routes.ts"],
};
const options = {
// ...
tags: [
// ...
{
name: "models",
"x-displayName": "Models",
// Note: markdown must not contain spaces after new line.
description: `
## Contribution
<SchemaDefinition schemaRef="#/components/schemas/Contribution" />
## Tags
<SchemaDefinition schemaRef="#/components/schemas/Tags" />
`,
],
"x-tagGroups": [
{
name: "models",
tags: ["models"],
},
]
}
/open-api.json
endpoint. Redocusaurus will use it to retrieve the data to display.import swaggerJsdoc from "swagger-jsdoc";
const specs = swaggerJsdoc(options);
app.get("/open-api.json", (req, res) => {
res.setHeader("Content-Type", "application/json");
res.send(specs);
});
# Note the /components/schemas/[component name] hierarchy.
# This is used to refer to these types in the endpoint
# documentation.
components:
schemas:
Contribution:
type: object
properties:
post_id:
type: string
format: uuid
parent_thread_id:
type: string
format: uuid
parent_post_id:
type: string
format: uuid
secret_identity:
$ref: "#/components/schemas/Identity"
required:
- post_id
- parent_thread_id
- secret_identity
/**
* @openapi
* posts/{postId}/contribute:
* post:
* summary: Replies to a contribution
* description: Posts a contribution replying to the one with id {postId}.
* tags:
* - /posts/
* - todo
* parameters:
* - name: postId
* in: path
* description: The uuid of the contribution to reply to.
* required: true
* schema:
* type: string
* format: uuid
* responses:
* 403:
* description: User is not authorized to perform the action.
* 200:
* description: The contribution was successfully created.
* content:
* application/json:
* schema:
* type: object
* properties:
* contribution:
* $ref: "#/components/schemas/Contribution"
* description: Finalized details of the contributions just posted.
*/
router.post("/:postId/contribute", isLoggedIn, async (req, res) => {
// The endpoint code
}
module.exports = {
// other config stuff
// ...
presets: [
// other presets,
[
"redocusaurus",
{
specs: [
{
routePath: "docs/engineering/rest-api/",
// process.env.API_SPEC is used to serve from localhost during development
specUrl:
process.env.API_SPEC ||
"[prod_server_url]/open-api.json",
},
],
theme: {
// See options at https://github.com/Redocly/redoc#redoc-options-object
redocOptions: {
expandSingleSchemaField: true,
expandResponses: "200",
pathInMiddlePanel: true,
requiredPropsFirst: true,
hideHostname: true,
},
},
},
],
],
}