3 Replies Latest reply on Apr 2, 2014 7:52 AM by eric.wittmann

    API Management Service Endpoint Format

    eric.wittmann

      Currently the API Management data model includes a version number for both applications and services.  The idea is that once a particular version of a Service is published it cannot be updated.  Instead, a new version of the Service must be created, modified, and then published.  The reason is that any Applications that are invoking the Service need to have some guarantee that the terms of the Service Contract will not change out from underneath them.

       

      Notea nice side-effect of this data model is that multiple versions of an *implementation* of a Service is also easily supported.

       

      However, this does mean that every time a Service is modified and re-published, it will have a new version associated with it.  Which also means that Application implementations may need to be updated with this information.  Why is this?  Because the Service's version number is currently encoded in the gateway endpoint.

       

      Specifically, the current endpoint format for the Gateway is as follows:

       

        http://domain:port:/gateway/[organizationId]/[serviceId]/[version]/path/to/resource

       

      As a result, the [version] portion of the endpoint URL will change every time a Service's details are changed.

       

      It is important to understand that the actual service *implementation* could be changed out from underneath the API Management system, since those back-end service implementations are likely independent.  In other words, if the back end service is a REST service, the developer could change the logic of the service and re-deploy it to the same REST endpoint without the API Management layer ever noticing.  I believe this is outside the scope of the API Management layer.

       

      It is also necessary to understand that Applications will be invoking the Service via a Contract.  Therefore, if a Service changes frequently, it might necessitate an Application to create new Contracts to the new Service versions.  It would also mean that the actual Application implementation would need to be updated to include the updated Gateway endpoint information for the Service.

       

      objectiser suggested that this might be too granular an approach and place too much of a burden on Application developers - requiring them to create new versions of their apps very frequently.

       

      The first question is this:

       

           Is it likely that Service configurations will often change?  This includes new versions of the Service's back end implementation, as well as API Management configuration changes to the Service such as modified Policies.

       

      If we answer YES to the above question, then I can think of various strategies to mitigate the Application developer's burden.  I will describe one possible solution (assuming a Yes answer above) as a reply (see below).

        • 1. Re: API Management Service Endpoint Format
          eric.wittmann

          Assuming we answer this question with "yes", I think we might consider publishing the Gateway endpoints from the Application perspective rather than the Service perspective.  Since the problem is ultimately that we don't want Application developers to build and release new versions of their Applications (think an iPhone app) each time a Service policy changes, we can solve this by calling Services through an Application focused layer of indirection.  This approach, coupled with the ability to update the Contracts known by the Gateway, should give us a reasonable solution.

           

          In other words, instead of the Gateway endpoint URL format described above, perhaps it should be:

           

            http://domain:port/gateway/[applicationOrgId]/[applicationId]/[applicationVersion]/[serviceOrgId]/[serviceId]/path/to/resource

           

          You will notice that the version of the service is missing from the URL format.  Note that all inbound requests need to include the API Key anyway.  This API Key identifies the Service Contract being used for the invocation of the Service.  The Contract includes the version of the Service, allowing the Gateway to lookup all of the details of the back-end system and policies to use for the invoke.  In reality (and for this reason), the [serviceOrgId] and [serviceId] aren't strictly necessary, but it makes for a more logically sensible endpoint format.

           

          How does this solve our problem?

           

          Well, because now whenever a Service changes, the Application developer can simply update their Application's Contracts to point to the newer version (and we could have an auto-migrate feature) and then re-publish the Application to the Gateway.  This will provide the Gateway with an updated set of Contracts with new Service configuration details.  Any Application implementation (e.g. iPhone app) would be built with a set of Gateway endpoints that would not need to change.

          • 2. Re: API Management Service Endpoint Format
            objectiser

            This does seem better, in terms of less disruption to the app developer.

             

            Is the API key scoped to the app org? Or is it globally unique within the system (even in a multi-tenant deployment)?

             

            Reason for asking is to determine whether the applicationOrgId and applicationId are technically required? Because if not, then from a URL perspective, I think it might be better (and simpler) to have:

             

              http://domain:port/gateway/[serviceOrgId]/[serviceId]/path/to/resource?apikey=xyz&version=123

             

            So using the apikey, we look up the app and its contract related to this service. The optional version can be used to select a particular app version if more than one exists, otherwise latest is used.

             

            The only purpose of the serviceOrgId/serviceId is to make explicit what service is being invoked. The issue is whether this is then verified against the details obtained using the apikey (ie. what happens if the application contract associated with the apikey is for a completely different service)? I guess this same question applies even if using the full URL in your example - but also means verifying that the apikey relates to the app org/id.

            1 of 1 people found this helpful
            • 3. Re: API Management Service Endpoint Format
              eric.wittmann

              The current plan is to have the API Key be scoped to a Contract.  The reason for this is so that a single Application can invoke the same Service but using different Contracts.  This could be useful, for example, for mobile apps that have a Free vs. Premium version.  It would be the same Application implementation (e.g. an Android app) but would use a different set of endpoints that perhaps had fewer restrictions or higher limits.

               

              So yes, the Gateway endpoint URL you suggested above would work, as would something even as simple as this:

               

                  http://domain:port/gateway/[apikey]/path/to/resource

               

              You already anticipated most of this.  The only thing to add is that your version information is not required, since we'll know all the relevant App and Service details just from the Contract.

               

              NoteI think we should support apikey as a query parameter but it should be highly discouraged.  I think the API Key should be passed via an HTTP Request Header whenever possible.

               

              So ultimately, after thinking this through while typing this reply I think I prefer the URL format from your reply (with the apikey as a header and with the version left off):

               

                  http://domain:port/gateway/[serviceOrgId]/[serviceId]/path/to/resource

               

              This would be the format used to invoke the Service, with the API Key passed as a header in the HTTP request.  The Gateway will look up the Contract and verify that it matches the Service information in the URL.  Then it will look up the Service details and use all of that information to invoke the back end system.

               

              NoteThis approach as the interesting side effect of never requiring applications to update their list of endpoints unless they add a new service.