Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 18, 2021 09:25 pm GMT

Documenting Express REST APIs with OpenAPI and JSDoc

As usual, this article isn't meant as an in-depth guide, as much 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!

Goals & Constraints

  • To document BobaBoard's REST API.
  • Standardize (and document) both the parameters and the return values of various endpoints.
  • The documentation should be as close as possible to the source code it describes.
  • The documentation should be served through a docusaurus instance hosted on a different server.

Final Result

Architecture

How everything interacts

Documentation

The BobaBoard Rest API Documentation

How To

Packages used

  • SwaggerJSDoc: to turn JSDocs into the final OpenAPI spec (served at /open-api.json).
  • Redocusaurus: to embed Redoc into Docusaurus. There are other options for documentation, like any OpenAPI/Swagger compatible tool (e.g. SwaggerUI), but Redoc is the nicest feeling one.

Configuration (Express)

OpenAPI Options

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: `# IntroWelcome to the BobaBoard's backend API. This is still a WIP.# Example SectionThis 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"],};

Open API endpoint

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);});

Type Spec

/types/open-api/contribution.yaml

# 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

Endpoint Documentation

This should be repeated for every API endpoint you wish to document.

/** * @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}

Configuration (Docusaurus)

docusaurus.config.js:

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,          },        },      },    ],  ],}

Original Link: https://dev.to/essentialrandom/documenting-express-rest-apis-with-openapi-and-jsdoc-m68

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To