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

[openapi-3] callbacks support #411

Closed
RomanHotsiy opened this issue Jan 21, 2018 · 16 comments
Closed

[openapi-3] callbacks support #411

RomanHotsiy opened this issue Jan 21, 2018 · 16 comments

Comments

@RomanHotsiy
Copy link
Member

OpenAPI 3.0 has callbacks support: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#operation-object

It would be great to support them in ReDoc but I don't have any idea of how to visualize them yet.
Let's share ideas/discuss it here.

@MikeRalphson
Copy link
Contributor

As the callback object wraps a pathItem object, in widdershins and openapi-gui I've rendered callbacks by repeating the pathItem template/component, but within a visually distinct containing <div> and in a separate tab, respectively. This handles the (admittedly unlikely) case of a callback object having its own callbacks.

@RomanHotsiy RomanHotsiy changed the title [react-rewrite] callbacks support [openapi-3] callbacks support Jun 1, 2018
@indolent-developer
Copy link

indolent-developer commented Aug 27, 2018

Is there any update on this issue?

@mtarkiai
Copy link

Hi - inquiring if this is being considered. IMO it would be a highly valuable feature.

@jmini
Copy link

jmini commented Aug 16, 2019

I would also be interested in such a feature.

Example OpenAPI spec: callback.yaml (based on the Swagger callbacks documentation page)

Rendering on the ReDoc Interactive Demo (not working yet).


As comparison how other tools are doing this:

OpenAPI-GUI:

mentioned by @MikeRalphson in #411 (comment)

OpenAPI-GUI displaying a simple callback spec

(more an editor than a display, but the interesting point in the "callbacks" tab)

Swagger-UI:

Swagger-UI displaying a simple callback spec


In my opinion, the problem with representing the callbacks under an operation makes sense from an Editing point of view but is not really what the used need:

But often when you look at a reference documentation you are more interested by "what can call me?", meaning by a list of all callback-operations that can be send by the server and that you need to handle.

An implementation could be:

  • Collect all operations from all callbacks defined in a spec.
  • Display them under a top level item (same rendering as the "Authentication" or as a "tag" in the ToC). Maybe with a text-color or an icon (next to the HTTP-Method) to indicate that this is a callback.
  • On the page that describes one callback-operation, add a note about the fact that it is a callback-operation and a deep link to the operation used to register. The path is also dependent from the registration.
  • On the normal operation that have callbacks defined, add a deep-link to the callback.

jmini added a commit to jmini/openapi-experiments that referenced this issue Aug 27, 2019
This is PoC to display callback events in ReDoc.
See Redocly/redoc#411
@jmini
Copy link

jmini commented Aug 27, 2019

Because our callbacks operation are always the same (we send a given Schema as Request-Body of a POST method), I have implemented a small PoC of what I have described above:

There is a main section "Callbacks events" and each callback is documented as separated entry in the tree.

Screenshot 2019-08-27 at 11 03 44

See spec: todoAppWithCallbacks.yaml (ReDoc live demo)


This is using the <SchemaDefinition schemaRef="..." /> markdown macro introduced by @nanov and discussed in #134.

I would prefer to have an <OperationDefintion operationId="…"> macro, this would be more generic and this way I would not have to write "Following request-body is send as POST request on the URL used to register the callback"

I did not investigate how to create links between the operation and the callback description.

@adamaltman
Copy link
Member

@jmini I don't know if the issue is your api definition, or with the implementation in Redoc. Here is what I noticed.

image

image

I think my confusion is mainly due to the api definition mismatching names event, event name and eventType. I suppose this could be resolved by tightening up that definition. Overall, this seems kind of cool.

I understand the desire to not have this:

Following request-body is send as POST request on the URL used to register the callback

However, I can't see where in the definition it would show that the callback is made via a POST (as opposed to a GET for example). In other words, I'm wondering how all of that could be grabbed automatically from your definition, and eliminate entirely the need for any special inline tags.

@jmini
Copy link

jmini commented Oct 31, 2019

First of all, thank you for your feedback and sorry for the delay.


I agree the OpenAPI spec that I have proposed to test this might not be ideal (design is not perfect), but is representative of the spec we are currently using in the project (some stuff can not be changed for backward compatibility).

I totally get your point about the events attribute in CallbackRegistration schema. It could be better.

Nevertheless this is not enforced by the OpenAPI spec, it is possible to have a registration operation that do not let you filter the kind of event you would like to receive (probably you do just get all events).


The prototype I have proposed in my previous comment is something that can be done with the current ReDoc version by adding the callback tag to create the “Callbacks events” in the tree:

https://github.com/jmini/openapi-experiments/blob/4eb908cdf0d3d5382b9e8da2a761669736f25b18/OpenAPI-specs/todoAppWithCallbacks.yaml#L18-L31


The Callbacks are defined under the path /callback for the POST operation
https://github.com/jmini/openapi-experiments/blob/master/OpenAPI-specs/todoAppWithCallbacks.yaml#L293-L319

If would be great if based of this input, ReDoc would automatically:

1a) Create the “Callbacks events” in the tree

In this section you see all the callback events that can be received, with a label indicating the HTTP method and maybe an other marked (I have used in my screenshot) to indicate that this node is not an endpoint defined by the server but an endpoint that the client needs to implement to receive callbacks

Screenshot Callbacks events

In my example there are only “POST” request callback, but you could also imagine that the sever is sending other calls to the client that is receiving the callback request.

Screenshot Callbacks with multiple HTTP request

1b) For each Callback event, instead of my quick hack "Following request-body is send as POST…", a complete representation of the operation should be displayed:

Screenshot Callback description

  • HTTP Method is important.
  • Mentioning that the endpoint URL is configurable (I have used /{your-endpoint} in my screenshot)
  • Responses: they are also important because there are setup where this is used to unsubscribe for the callback (receiving server can return specific code in response to the callback message to indicate that it is no longer interested in callbacks).

2a) In the Operation where the callbacks are defined:

There should be a section that indicates that callbacks are defined for this operation:

Screenshot operation

I am not sure about the position, it should probably be after "Responses".
The links should allow to jump to the corresponding event in the "Callbacks events" section.

2b) The other way around: in one page displaying one callback, you could also imagine a link to the registration operation (the operation that defines the callback in the OpenAPI Spec).


I hope this makes my vision for Callbacks in ReDoc more clear. If not feel free to ask.

@moritztk
Copy link

Hi everyone, are there any news regarding the callback support of redoc?

@forivall
Copy link

forivall commented Apr 27, 2020

It appears to be supported in my currently used 2.0.0-rc.27

Fixed by #1224

@RomanHotsiy
Copy link
Member Author

Thanks @forivall

Yes. We added support for this since rc.27: #1224

@jaspersorrio
Copy link

jaspersorrio commented Jun 29, 2020

Are callbacks supported for redoc-cli?

I followed the guide to add callbacks at https://swagger.io/docs/specification/callbacks/.

Can't seem to get it to build properly.

Builds just fine on swagger.

The version of redoc-cli is 0.9.7.

npx redoc-cli --version
0.9.7

No Callback tab on redoc

Screenshot from 2020-06-29 22-34-13

Works on Swagger

Screenshot from 2020-06-29 22-34-06

Edited: Added images.

@RomanHotsiy
Copy link
Member Author

@jaspersorrio what version of redoc-cli are you using? any other details you can provide?

@RomanHotsiy
Copy link
Member Author

Can't seem to get it to build properly.

Could you explain what this means? Can you share your definition? or minimal reproducible sample?

@jaspersorrio
Copy link

jaspersorrio commented Jun 29, 2020

Hi @RomanHotsiy,

You may use this snippet to reproduce the "bug".

openapi: 3.0.1
info:
  title: example API Documentation BETA (latest)
  description: "This page contains the documentation on how to use example through API calls.\n
    \n
    <h3>Previous API versions</h3>
    <a href='/api/v1'>API V1.0</a>"
  termsOfService: https://example.sg/terms-of-use
  contact:
    email: [email protected]
  version: "1.1"
servers:
- url: https://api.example.sg
- url: https://api.example.dev

tags:
  - name: Chat
    description: Chat with EXAMPLE dedicated customer service support without the need to leave your app by starting and replying chat sessions with example Chat Api.

  - name: Chat_Model
    x-displayName: The Chat Model
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Chat" />

x-tagGroups:
  - name: General
    tags:
      - Chat
  - name: Models
    tags:
      - Chat_Model
 
paths:
  /api/v1.1/chat:
    post:
      tags:
      - Chat
      summary: Start a Chat

      callbacks:	
        ReplyChatEvent: 	
          $ref: "#/components/callbacks/ReplyChatEvent"
      requestBody:
        $ref: "#/components/requestBodies/ChatBody"
        
      responses:
        200:
          description: Success
          content: 
            application/json:
              schema:
                required:
                  - success
                  - chatId
                type: object
                properties:
                  success: 
                    type: boolean
                    example: true
                  chatId:
                    $ref: '#/components/schemas/Chat/properties/chatId'

  /api/v1.1/chat/{id}:
  
    post:
      tags:
      - Chat
      summary: Reply a Chat
      parameters:
        - in: path
          name: id
          required: true
          description: The chatId you want to reply to.
          schema:
            $ref: '#/components/schemas/Chat/properties/chatId'

      requestBody:
        $ref: "#/components/requestBodies/ChatBody"
        
      responses:
        200:
          description: Success
          content: 
            application/json:
              schema:
                required:
                  - success
                  - chatId
                type: object
                properties:
                  success: 
                    type: boolean
                    example: true
                  chatId:
                    $ref: '#/components/schemas/Chat/properties/chatId'
components:

  # 
  # COMPONENTS > CALLBACKS
  # 

  callbacks:	
    ReplyChatEvent:	
      '{$request.body#/responseUrl}':	
        post:	
          requestBody:   # Contents of the callback message	
            required: true	
            content:	
              application/json:	
                schema:	
                  $ref: "#/components/schemas/Chat"	
          responses:   # Expected responses to the callback message	
            '200':	
              description: REQUIRED - Your server returns this code if it accepts the callback
  
  #
  # COMPONENTS > REQUEST BODIES
  #
  requestBodies:
    ChatBody: 
      required: true
      content: 
        application/json: 
          schema: 
            type: object
            required: 
              - subject
              - message
              - responseUrl
            properties:
              subject:
                type: string
                example: Loctite 243 Threadlocker 50ml
                description: The subject of the thread
              message:
                type: string
                example: Can we get a cheaper price?
                description: The message to be sent
              responseUrl:
                description: The webhook that example should make the POST request when the replying party replies.
                type: string
                example: https://webhook.site/e1d8a451-9a4f-4d2b-8080-dfdb8ffa511c
   
  #
  # COMPONENTS > SCHEMAS
  #
  schemas:
    Chat:
      type: object
      properties: 
        chatId: 
          description: The chat's _id. Required when replying to a Chat.
          type: string
          example: 8e59d4cc-34ef-4ad4-a922-01bc2d347d24
        message: 
          description: The chat's message / content
          type: string
          example: This order will arrive on monday
        subject: 
          description: The subject of the chat
          type: string
          example: Order Id INV-2002-200

  securitySchemes:
    apiKey:
      type: apiKey
      name: X-example-API-KEY
      in: header
      
security:
  - apiKey: []

@RomanHotsiy
Copy link
Member Author

I just run openapi-cli and I can see callbacks.

image

The latest version of redoc-cli is:

npx redoc-cli --version
0.9.8

You must have cached the older one. Try adding version explicitly npx [email protected]

@jaspersorrio
Copy link

jaspersorrio commented Jun 29, 2020

@RomanHotsiy, you just saved me so much time, I am so grateful for your help.

Thank You so much!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants