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-First, Forked Collection Workflow #8940

Open
therockstorm opened this issue Aug 15, 2020 · 9 comments
Open

Support OpenAPI-First, Forked Collection Workflow #8940

therockstorm opened this issue Aug 15, 2020 · 9 comments

Comments

@therockstorm
Copy link

therockstorm commented Aug 15, 2020

We use a Postman Team account to publish Collections and Documentation and drive everything off of the OpenAPI spec during CI in an automated fashion. An ideal workflow would be,

  1. Update OpenAPI spec
  2. Upload to Postman via Update Schema, triggering the Collection created from that schema and the Documentation created from that Collection to automatically update
  3. Customers of our API can fork the Collection so they can optionally pull in updates as they're made

Here's another explanation of what we're after.

Unfortunately, reality is quite different. Here is our current workflow to get this working,

  1. Update OpenAPI spec
    1. The spec must explicitly include the Authorization and Content-Type headers in each endpoint in order to show correctly in Postman Documentation's code samples (link to issue) as described in this issue comment. We're also impacted by Auth issues described here, here, and here.
  2. Resolve the schema to a single file using openapi-generator-cli's openapi-yaml generator because the tool in the next step returns schema type not provided errors for multi-file specs referenced via $ref
  3. Use a forked version of Postman's openapi-to-postmanv2 tool to convert the spec to a Postman collection. The forked version contains the following fixes
    1. This PR ensures IDs for the same endpoints remain unchanged. This is crucial because otherwise when you update the collection, it removes all the old endpoints and creates all new ones. This, in turn, changes the URLs for each endpoint if you're using Postman's Documentation. Here's another issue from 2017 describing the problem.
    2. This PR so you can pass configuration via the CLI
    3. Increased stackLimit from 10 to 20 since it's not configurable and sets some request bodies to <Error: Too many levels of nesting to fake this schema> otherwise
  4. Because of 1. i. above, we next have to run a sed command to remove the Content-Type header automatically added by the openapi-to-postman tool so only the manually added one remains, otherwise it shows up twice in the Collection and Documentation. I'm not sure why this automatically included header doesn't show up in code samples but the manually added one does.
  5. Convert the schema to JSON because Postman's Update Schema API requires it as a string and it's not trivial to escape YAML as a string inside a JSON value
  6. Upload to Postman via Update Schema, this does nothing to Collections created from the schema, so...
    1. Could be solved with this issue
  7. Upload openapi-to-postman output via Update Collection, triggering the Documentation created from that Collection to automatically update.
  8. Our customers must either continue using their old collections or import the new one and lose all their changes since forking/version control is only available within teams.

Related issues

Is there a simpler, already existing workflow to accomplish what we're after? This seems like a relatively normal use-case: update one file (the OpenAPI spec) and have all downstream artifacts ("Golden" Collection, Documentation, Forked Collections, SDKs) automatically pull in those changes.

@therockstorm therockstorm changed the title Support OpenAPI-first Workflow Support OpenAPI-first, Forked Collection Workflow Aug 15, 2020
@therockstorm therockstorm changed the title Support OpenAPI-first, Forked Collection Workflow Support OpenAPI-First, Forked Collection Workflow Aug 15, 2020
@sankalp0o
Copy link

@therockstorm thanks for the detailed explanation! This helps us understand the various gaps in the workflow and we will work towards addressing all of them.

Have you tried updating the downstream artifacts using this workflow - https://learning.postman.com/docs/designing-and-developing-your-api/validating-elements-against-schema/#updating-api-elements?
If this works for you, we can expose the same functionality via an API. That can potentially solve 3, 7, and 8.

As for the other issues that you mentioned, we'll do some digging and get back to you. Is it possible to see the schema that you're using? That might help us debug the content-type problem.

@therockstorm
Copy link
Author

therockstorm commented Aug 16, 2020

Thanks for the quick reply @sankalp0o!

Have you tried updating the downstream artifacts using this workflow - https://learning.postman.com/docs/designing-and-developing-your-api/validating-elements-against-schema/#updating-api-elements?
If this works for you, we can expose the same functionality via an API. That can potentially solve 3, 7, and 8.

I've seen this workflow, but it seems much more manual than the openapi-to-postman tool. If exposed though the API, that would help. However, I just ran a simple test and it didn't pick up my change, so I fear this would just introduce another list of workarounds.

  1. Create a new API in Postman using the default schema and "Generate Collection" from that schema
  2. Go to the Develop tab and validate the schema, receive green checkmark
  3. Go to Define tab and change path./user.get.parameters id from integer/int32 to string/uuid and save
  4. Go to the Develop tab and "Validate Again", it's still valid but shouldn't be. The collection contains an integer for id and I've just said it's now a uuid.

Further, I don't see how this addresses 8. What we want is for anyone to be able to fork any Collection so they can pull upstream changes in when updates happen. So if AWS publishes a collection for the S3 API, for example, and makes a change to their collection (e.g., adding a new endpoint), I'd want to be able to pull that change into my forked collection without losing any changes I've made to other parts of the collection. To my knowledge, that's only possible within teams right now.

Is it possible to see the schema that you're using? That might help us debug the content-type problem.

Minimal reproducible schema

openapi: 3.0.3
info:
  title: Platform API
  version: "1.0"
servers:
- url: https://www.example.com
tags:
- name: files
- name: oauth2
paths:
  /files:
    post:
      operationId: createFile
      requestBody:
        content:
          application/vnd.api+json:
            schema:
              type: string
        required: true
      responses:
        "201":
          content:
            application/vnd.api+json:
              schema:
                type: string
          description: Created
      security:
      - OAuth2: []
      tags:
      - files
components:
  schemas: {}
  securitySchemes:
    OAuth2:
      flows:
        clientCredentials:
          scopes: {}
          tokenUrl: /oauth2/token
      type: oauth2

The resulting Postman Documentation. Notice the code samples contain neither the Authorization nor the Content-Type headers.

The fix it, we manually add both headers as parameters to each endpoint,

Workaround schema

openapi: 3.0.3
info:
  title: Platform API
  version: "1.0"
servers:
- url: https://www.example.com
tags:
- name: files
- name: oauth2
paths:
  /files:
    post:
      operationId: createFile
      parameters:
      - explode: false
        in: header
        name: Authorization
        required: true
        schema:
          example: Bearer {{ACCESS_TOKEN}}
          type: string
        style: simple
      - explode: false
        in: header
        name: Content-Type
        required: true
        schema:
          example: application/vnd.api+json
          type: string
        style: simple
      requestBody:
        content:
          application/vnd.api+json:
            schema:
              type: string
        required: true
      responses:
        "201":
          content:
            application/vnd.api+json:
              schema:
                type: string
          description: Created
      security:
      - OAuth2: []
      tags:
      - files
components:
  schemas: {}
  securitySchemes:
    OAuth2:
      flows:
        clientCredentials:
          scopes: {}
          tokenUrl: /oauth2/token
      type: oauth2

The resulting Postman Documentation. Notice the code samples now have both headers, but the Content-Type header is now duplicated in both the Postman Collection and Documentation. To workaround this, we run sed 's|,{"key":"Content-Type","value":"application/vnd.api+json"}||g' collection.json > updated.json to remove the automatically added Content-Type header, leaving only the manually added one that correctly appears in code samples.

@therockstorm
Copy link
Author

Any update on this @sankalp0o @abhijitkane @vvs11 @Raja-Simha?

@a85
Copy link
Contributor

a85 commented Aug 20, 2020

@therockstorm We are looking into this. One question: are you also generating the OpenAPI schema from your codebase through annotations or manually writing that?

@therockstorm
Copy link
Author

therockstorm commented Aug 20, 2020

Thanks, @a85! We start everything from the manually written OpenAPI schema. So an example of adding an endpoint would be,

  1. Update OpenAPI schema
  2. Generate server-side domain objects from schema
  3. The Vert.x framework imports the schema to handle things like Auth and validation, more info
  4. Once the endpoint is implemented, we deploy our API and steps 2-8 in my original message above run during CI

@abhijitkane
Copy link
Member

@therockstorm A few updates:

In the OpenAPI<->Collection module, we're working on two fixes:

  1. The Authorization header for simple auth types (API Key / Bearer Token) should also show up in the example request headers (and by extension, in the generated documentation). We're working to get this out in production within a week.
  2. Better Collection<>Schema validation in the Postman app. This should let you use the Postman UI/API to update the schema, and then update all linked collections to the include endpoints/additions from the updated schema in a few clicks.

On the documentation module, we've recently pushed out fixes for #4912 and #4244 (they're the same issue).

I'll keep you posted on #1 and #2 - they should make your current workflow significantly smoother.

For the other concerns raised:

  1. Content-Type in the examples - in many cases, the library used to make the request can add the content-type header (for urlencoded/multipart/JSON bodies). Can you share any library/header combination where this isn't working well?
  2. Upoading YAML files to update schemas - we're looking to support direct file uploads to get around the escaping problem.

I'd also be interested to hear about your use of the forked OpenAPI->Postman module to maintain request IDs. The comment on postmanlabs/openapi-to-postman#224 indicates that the request IDs change even if you provide them in the Update Collection API call.

@therockstorm
Copy link
Author

Great to hear about the fixes and thanks for keeping me updated, @abhijitkane!

Content-Type in the examples - in many cases, the library used to make the request can add the content-type header (for urlencoded/multipart/JSON bodies). Can you share any library/header combination where this isn't working well?

We follow the json:api spec for our API, which requires clients to send all requests with the Content-Type: application/vnd.api+json header. I realize most APIs don't follow this spec so the code samples may work for them, but for APIs that require specific Content-Types for endpoints, all code samples with request bodies fail with 415 "Unsupported Media Type" status codes. So if the Collection<>Schema validation workflow is the proposed solution to our workarounds, we'd need either the doc to include Content-Type in code samples or a way to specify it ourselves (like we do today by explicitly adding it to OAS) without leading to it showing up twice in the doc.

I'd also be interested to hear about your use of the forked OpenAPI->Postman module to maintain request IDs.

The sourcemap change from that PR keeps the item.[].ids stable across updates, so that must prevent the documentation URLs from changing. I think what @kevinswiber is saying is that the item.[].request.id still changes on updates, which makes diffs harder to reason about in Postman Version Control. Our primary concern is the URLs not changing, though, so I went ahead and merged that change into our fork and we're using it.

Is there a way to accomplish our end-users forking our "master" Collection into their accounts so they can pull upstream changes in when we make updates (described in more detail via an S3 example in this comment? In my opinion, this is an important missing feature if it's not possible outside of Postman Teams.

Thanks for taking the time to look into this. If Postman can nail the ideal workflow I outlined above, it'd be the best way to develop and consume REST APIs.

@niklaswallerstedt
Copy link

@abhijitkane any updates/timeline when this will be available?

  1. The Authorization header for simple auth types (API Key / Bearer Token) should also show up in the example request headers (and by extension, in the generated documentation). We're working to get this out in production within a week.

Facing this issue and appreciate @therockstorm's use case description as it's something similar we're working towards in our team.

@VShingala
Copy link
Member

VShingala commented Sep 17, 2020

@niklaswallerstedt We have been working on the mentioned task by you under issue #7914 and the issue is already fixed in the corresponding open-source module via postmanlabs/openapi-to-postman#286.

It will be available on App with an upcoming release next week. Feel free to add any additional comments on the issue mentioned above.

@sankalp0o sankalp0o removed their assignment Apr 17, 2021
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