Custom Schema Definitions

While Serverpod automatically generates OpenAPI schemas from your Dart classes, there are cases where you might need to define custom schemas or override the generated ones. This page explains how to create and use custom schema definitions in your Serverpod Swagger documentation.

Why Use Custom Schemas?

Custom schemas are useful when you need to:

  • Define complex data structures that don't have corresponding Dart classes
  • Override the automatically generated schemas with more detailed information
  • Add examples, descriptions, or constraints to your schemas
  • Define schemas for third-party libraries or external systems

Creating Custom Schema Definitions

You can define custom schemas by creating a YAML file with your schema definitions. Create a file named openapi_schemas.yaml in your project root:

openapi_schemas.yaml
1components:
2  schemas:
3    CustomResponse:
4      type: object
5      properties:
6        status:
7          type: string
8          enum: [success, error, pending]
9          description: The status of the operation
10        data:
11          type: object
12          description: The response data
13          nullable: true
14        message:
15          type: string
16          description: A human-readable message
17      required:
18        - status
19    PaginatedResult:
20      type: object
21      properties:
22        items:
23          type: array
24          items:
25            type: object
26          description: The list of items in the current page
27        total:
28          type: integer
29          format: int32
30          description: Total number of items
31        page:
32          type: integer
33          format: int32
34          description: Current page number
35        pageSize:
36          type: integer
37          format: int32
38          description: Number of items per page
39      required:
40        - items
41        - total
42        - page
43        - pageSize

The generator will include these schema definitions in the generated OpenAPI specification.

Referencing Custom Schemas in Endpoint Annotations

You can reference your custom schemas in endpoint annotations using the @Schema annotation:

example_endpoint.dart
1/// Get paginated users
2/// 
3/// Returns a paginated list of users
4('/users')
5('GET')
6(response: 'PaginatedResult')
7Future<String> getUsers(Session session, {('page') int page = 1, ('pageSize') int pageSize = 10});
8
9/// Create user
10/// 
11/// Creates a new user and returns a custom response
12('/users')
13('POST')
14(response: 'CustomResponse')
15Future<String> createUser(Session session, User user);

In this example, the getUsers endpoint returns a PaginatedResult schema, and the createUser endpoint returns a CustomResponse schema.

Adding Examples to Custom Schemas

You can add examples to your custom schemas to help API consumers understand the expected data format:

openapi_schemas.yaml
1components:
2  schemas:
3    CustomResponse:
4      type: object
5      properties:
6        status:
7          type: string
8          enum: [success, error, pending]
9          description: The status of the operation
10        data:
11          type: object
12          description: The response data
13          nullable: true
14        message:
15          type: string
16          description: A human-readable message
17      required:
18        - status
19      example:
20        status: success
21        data:
22          id: 123
23          name: "John Doe"
24        message: "User created successfully"

Overriding Generated Schemas

If you want to override a schema that is automatically generated from a Dart class, simply define a schema with the same name in your YAML file:

openapi_schemas.yaml
1components:
2  schemas:
3    User:
4      type: object
5      properties:
6        id:
7          type: integer
8          format: int64
9          description: The unique identifier for the user
10        email:
11          type: string
12          format: email
13          description: The user's email address
14        name:
15          type: string
16          description: The user's full name
17        role:
18          type: string
19          enum: [admin, user, guest]
20          description: The user's role
21      required:
22        - email
23        - name
24      example:
25        id: 123
26        email: "john.doe@example.com"
27        name: "John Doe"
28        role: "user"

Using References in Schema Definitions

You can use references to reuse schema components within your definitions:

openapi_schemas.yaml
1components:
2  schemas:
3    Error:
4      type: object
5      properties:
6        code:
7          type: string
8          description: Error code
9        message:
10          type: string
11          description: Error message
12      required:
13        - code
14        - message
15    
16    ApiResponse:
17      type: object
18      properties:
19        data:
20          type: object
21          nullable: true
22          description: Response data
23        error:
24          $ref: '#/components/schemas/Error'
25          description: Error information if the request failed
26        success:
27          type: boolean
28          description: Whether the request was successful
29      required:
30        - success

Combining Custom Schemas with Security Definitions

You can combine custom schemas with security definitions in a single YAML file:

openapi_custom.yaml
1security:
2  - BearerAuth: []
3
4components:
5  securitySchemes:
6    BearerAuth:
7      type: http
8      scheme: bearer
9      bearerFormat: JWT
10      description: Enter your JWT token in the format 'Bearer {token}'
11  
12  schemas:
13    ApiResponse:
14      type: object
15      properties:
16        data:
17          type: object
18          nullable: true
19        error:
20          type: object
21          nullable: true
22          properties:
23            code:
24              type: string
25            message:
26              type: string
27        success:
28          type: boolean
29      required:
30        - success

Next Steps