Server
OpenAPI (Swagger)

OpenAPI

OpenAPI is a specification for machine-readable interface files for describing, producing, consuming, and visualizing REST APIs. OpenAPI files allow you to describe your entire API in the JSON or YAML format. It has routes including all possible response types in all possible status codes together with all possible request types. So a well-written OpenAPI file can be used as a reference by the client to understand the API easier.

feTS uses this specification to generate the API documentation and the client SDKs. Even on the server side, it allows you to play with your API with a playground. Or you can even use any other OpenAPI-compliant tool like Postman to test your API.

feTS creates two endpoints based on the defined routes by default;

Customizing OpenAPI

You can give 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 give a version to your API
    }
  }
})

More Information on Routes

You can add more information to your routes such as operationId, description, tags and deprecated to make the OpenAPI specification more detailed.

Learn more about operations in OpenAPI (opens in a new tab)

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

Models / Subschemas

You can define models as subschemas and use them in your routes. This is useful when you have repeating structures in your API. feTS respects json schema's $ref keyword in this case.

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

const router = createRouter({
  components: {
    schemas: {
      // Define a model named User
      User: {
        type: 'object',
        properties: {
          id: { type: 'string' },
          name: { type: 'string' },
          email: { type: 'string' }
        }
      }
    }
  } as const
})
  // Use the User model in different routes
  .route({
    method: 'GET',
    path: '/users',
    schemas: {
      responses: {
        200: {
          type: 'array',
          items: {
            $ref: '#/components/schemas/User'
          }
        }
      }
    } as const,
    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
        }
      }
    } as const,
    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 probably don't want to expose the schema to the public. In this case, you can pass false to swaggerUiEndpoint and oasEndpoint options to disable them.

const router = createRouter({
  swaggerUiEndpoint: false, // or process.env.NODE_ENV === 'production'
  oasEndpoint: false
})