Forum Discussion

HenrikHL's avatar
HenrikHL
Frequent Contributor
4 years ago

Pitfalls when publishing an API referencing Domains that are unpublished

Hi,

I have stumbled onto a problem when publishing APIs. I have started using the Domains to store common types and components shared among APIs. The Domains are not yet published. When I publish my API my impression was that the API was stable - this is not the case, as components referred to in Domains that are not published yet, can change!

I am surprised that Swaggerhub does not check for references to unpublished Domains before publishing an API!

How should this be mananged? How does other people manage this?

  • the webhook listener should not be deployed on the SwaggerHub VM. I would suggest a small Linux instance on the same sub-net. 

    there I would run a small node.js listener that accepts the POST from SwaggerHub and parses the json copy of the spec that is included in the POST payload. 

    the parsing would look for $refs that contain the “…/domain/…” url inductive of a domain reference. Parse out the domain location (organization), name and version contained the the url, then use either the swaggerhub cli or the SwaggerHub Registry Api to publish that domain/version. Repeat until the spec is completely parsed. 

    the node.js code to do this should be fairly simple, you’ll just need to be able to find the $refs that are remote anchors, then pick out the 3 sub-strings that describe the domain. 

  • HenrikHL's avatar
    HenrikHL
    Frequent Contributor

    Expected behavior when "Publish API" button is pressed (this is for both APIs and Domains)

    1). Check if there are references to Domains

    2). if "yes" - check if the references point to domains that are unpublished

    3). if "yes" - force user to publish Domain before publishing API (or even better - SwaggerHub can offer to publish the Domain)

     

    Alternatively when pressing the "Publish API" button - give the option to resolve ALL references...

     

    pseudo code

    function publish(Domain/API, doResolve) {
      if not doResolve then
        loop through "all references" in Domain/API
          if reference is located in unpublished Domain then
            call publish(unpublished Domain, false)
      else resolve references in Domain/API
      make Domain/API published
    }

        

    • joejoyce's avatar
      joejoyce
      Staff

      Hey HenrikHL, thanks for getting in touch. This sounds like it could be a good use case to bring to the SwaggerHub product team. I'm interested to hear more about the scenario. Have you been finding that publishing an API that references unpublished domains is causing issues for your users or workflows?

      • HenrikHL's avatar
        HenrikHL
        Frequent Contributor

        Hi joejoyce - thanks for reaching out.

        I have previously released APIs (by not using Domains) - this works fine as once the API is published - it cannot be modified.

        After talking with some of your colleagues I was introduced to Domains - which sounds like a great idea (we reuse a lot of definitions between different APIs). We are about to release the next big API (actually we are going to release 4 new APIs based on Domains). There are a lot of worries that when publishing the API domains can still change - as in types, names, everything referenced from an API to a Domain can change!

        I would suspect this is an error as the hole point of publishing an API is to make it readOnly.

         

        If you want a concrete example I can give one here:

        CustomerAPI v1.0.0 containing a GET /customers

        in the CustomerAPI definition of the above response a reference to the Customer-component defined in GlobalDomain v1.0.0 is inserted:

         

        /customers:
          get:
            responses:
              '200':
                description: Request successful
                content:
                  application/json:
                    schema:
                      $ref: 'https://api.swaggerhub.com/domains/XXXorg/GlobalDomain/1.0.0#/components/schemas/customer'

         

        Now in GlobalDomain v1.0.0 i start by defining Customer like this:

         

        components:
          schemas:
            customer:
              type: string
              ...

         

        (To make it simple - customer is a type: string)

        I then publish CustomerAPI v1.0.0 with the endpoint GET /customers the response here is a string (for now)

         

        Someone then opens GlobalDomain v1.0.0 (since it is not published and therefore NOT readOnly) and changes customer to:

         

        components:
          schemas:
            customer:
              type: integer
              ...

         

        (Changes type:string -> type:integer)

        Now the published GET /customers endPoint of CustomerAPI returns an integer instead of a string!

         

        I would be glad to take this up with the SwaggerHub product team - let me know how to contact them and I will do so 🙂