Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OpenAPI Callbacks #727

Open
2 tasks done
MatanYadaev opened this issue Jun 12, 2023 · 7 comments
Open
2 tasks done

Support OpenAPI Callbacks #727

MatanYadaev opened this issue Jun 12, 2023 · 7 comments
Labels
feature request New feature to be added

Comments

@MatanYadaev
Copy link

MatanYadaev commented Jun 12, 2023

Prerequisites

  • I have written a descriptive issue title
  • 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
@mcollina
Copy link
Member

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

@mcollina mcollina added good first issue Good for newcomers feature request New feature to be added labels Jun 13, 2023
@MatanYadaev
Copy link
Author

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.

@mcollina
Copy link
Member

mcollina commented Jul 3, 2023

Have you tried using the transform option?

@MatanYadaev
Copy link
Author

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

@mcollina
Copy link
Member

mcollina commented Jul 3, 2023

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

@MatanYadaev
Copy link
Author

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

@mcollina
Copy link
Member

mcollina commented Jul 4, 2023

I currently have no bandwidth to investigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature to be added
Projects
None yet
Development

No branches or pull requests

2 participants