fastify-swagger icon indicating copy to clipboard operation
fastify-swagger copied to clipboard

Support OpenAPI Callbacks

Open MatanYadaev opened this issue 1 year ago • 7 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

OpenAPI 3 has a concept of callbacks, which means, async responses for an endpoint.

Currently, Fastify Swagger doesn't support this feature.

Motivation

It's part of the OpenAPI 3 specification. Many APIs use this feature.

Example

Defining the route and the schema:

app.post(
	'/start-process/:id',
	{
		schema: {
			summary: 'Start a process',
			operationId: 'startProcess',
			params: {...},
			body: {...},
			response: {...},
			// Callbacks configuration:
			callbacks: {
				onStart: {
					'{$request.body#/callbackUrl}': {
						post: {
							summary: 'Callback when process starts',
							operationId: 'onStart',
							requestBody: {
								type: 'object',
								properties: {
									id: {
										type: 'string',
									},
								},
							},
							response: {
								200: {
									description: 'Your server received the callback',
								},
							},
						},
					},
				},
			},
		},
	},
	() => {
		// Endpoint logic
	},
);

Should generate this OpenAPI spec:

openapi: 3.0.3
info:
  title: Fastify Project
  description: Fastify Project
  version: 0.0.0
components:
  schemas: {}
paths:
  "/start-process/{id}":
    post:
      operationId: startProcess
      summary: Start a process
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                callbackUrl:
                  type: string
                  format: uri
      parameters:
        - schema:
            type: string
          in: path
          name: id
          required: true
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
      // Callbacks:
      callbacks:
        onStart:
          '{$request.body#/callbackUrl}':
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      type: object
                      properties:
                        status:
                          id: string
              responses:
                "200":
                  description: Your server received the callback

MatanYadaev avatar Jun 12 '23 07:06 MatanYadaev

Thanks for reporting! Would you like to send a Pull Request to address this issue? Remember to add unit tests.

mcollina avatar Jun 13 '23 08:06 mcollina

Hi @mcollina, I tried implementing it and found it a bit challenging. I didn't have enough time to learn and research the project. Could you perhaps suggest a workaround to manually insert callbacks inside the generated OpenAPI Spec? Thanks for your time.

MatanYadaev avatar Jul 03 '23 07:07 MatanYadaev

Have you tried using the transform option?

mcollina avatar Jul 03 '23 07:07 mcollina

@mcollina No, but it will work for me. I am still wondering if there is a better workaround, that is not centralized, for example, make the transform per route, and not in the plugin registration. Something like that:

app.route({
  url: '/users',
  method: 'POST',
  schema: {...},
  transform: (schema) => {
    // Transform here
  },
});

MatanYadaev avatar Jul 03 '23 13:07 MatanYadaev

That would be awesome to implement. You should store that function somewhere in:

app.route({
  url: '/users',
  method: 'POST',
  schema: {...},
  config: {
    swaggerTransform: (schema) => {
      // Transform here
    }
  }
});

mcollina avatar Jul 03 '23 13:07 mcollina

@mcollina I just tried the transform method and it seems to not use the callbacks property I added to the route schema.

MatanYadaev avatar Jul 03 '23 13:07 MatanYadaev

I currently have no bandwidth to investigate.

mcollina avatar Jul 04 '23 08:07 mcollina