ServerOpenAPI (Swagger)

OpenAPI Implementation

OpenAPI offers a framework for building interface files that are machine-readable. These files help in describing, generating, consuming, and visualizing REST APIs. You can illustrate your complete API in JSON or YAML format with OpenAPI. This includes routes, all potential response types and status codes, and all possible request types. Consequently, a thoroughly composed OpenAPI file can act as a reference for clients, making it easier to understand the API.

In feTS, this specification is used to generate API documentation and client SDKs. Even on the server-side, it enables interaction with your API via a playground. Alternatively, you can utilize any other OpenAPI-compliant tool like Postman for API testing.

By default, feTS creates two endpoints based on the defined routes:

  • /openapi.json - Outputs the OpenAPI specification in JSON format
  • /docs - Provides a Swagger UI as an API playground

Customizing OpenAPI

You have the option to assign a title and a description to your API:

createRouter({
  openAPI: {
    info: {
      title: 'My API',
      description: 'My API description',
      version: '1.0.0' // You can even assign a version to your API
    }
  }
})

Enhancing Route Information

You can enrich your routes with additional information like operationId, description, tags, and deprecated. This additional data can make your OpenAPI specification more comprehensive.

Learn more about operations in OpenAPI.

createRouter().route({
  /* OpenAPI specific information */
  operationId: 'getUsers',
  description: 'Get all users',
  tags: ['users'],
 
  /* Regular configuration */
  method: 'GET',
  path: '/users'
  /* .. */
})

Models / Subschemas

You can create models as subschemas and incorporate them into your routes. This is especially useful when your API has recurring structures. feTS honors the $ref keyword in json schema in this context.

These models will be presented as models in the OpenAPI specification.

const router = createRouter({
  openAPI: {
    components: {
      schemas: {
        // Define a model named User
        User: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            name: { type: 'string' },
            email: { type: 'string' }
          }
        }
      }
    }
  }
})
  // Use the User model in different routes
  .route({
    method: 'GET',
    path: '/users',
    schemas: {
      responses: {
        200: {
          type: 'array',
          items: {
            $ref: '#/components/schemas/User'
          }
        }
      }
    },
    handler() {
      return Response.json(users)
    }
  })
  .route({
    method: 'GET',
    path: '/users/:id',
    schemas: {
      responses: {
        200: {
          $ref: '#/components/schemas/User'
        },
        404: {
          type: 'object',
          properties: {
            message: { type: 'string' }
          },
          required: ['message'],
          additionalProperties: false
        }
      }
    },
    handler() {
      const user = users.find(user => user.id === params.id)
      if (!user) {
        return Response.json({ message: 'User not found' }, { status: 404 })
      }
      return Response.json(user)
    }
  })

Disabling OpenAPI

For production, you may not want to expose the schema to the public. In this case, you can pass false to swaggerUI.endpoint and openAPI.endpoint options to disable them.

const router = createRouter({
  swaggerUI: {
    endpoint: false // or process.env.NODE_ENV !== 'production'
  },
  openAPI: {
    endpoint: false
  }
})