WSO2 vs GraphQL: overview and comparison of open source API management products

WSO2 vs GraphQL: overview and comparison of open source API management products

In recent years, many organizations have provided public access to their digital ecosystems via APIs. This has transformed APIs from being a tool, into being a product. At the same time, wide adoption of microservices has led to an increased number of internal APIs used by organizations as well.

The effect of these changes is that since 2005, the number of APIs has grown from a mere curiosity to an overwhelming trend. This is reflected by the programmableweb public-API catalogue, which reports that the total API count has grown from just a handful in 2005 to over 22,000 today as demonstrated in the figure below.

The growth over time of the ProgrammableWeb API directory to more than 22,000 entries (https://www.programmableweb.com/news/apis-show-faster-growth-rate-2019-previous-years/research/2019/07/17)

With such strong growth of both public and internal APIs, there is a clear need for special tools and techniques to manage the full life cycle of APIs and provide a better experience for API clients. This is where API management solutions play an important role. They can offer a variety of features however, according to Forrester’s definition, they generally include at least three core components: an API user portal, a business admin portal, and an API Gateway.

Comparing API management solutions

The main goal of this research was to evaluate several popular open-source API management solutions. These evaluations were done with respect to Grid Dynamics’ own requirements and were aimed at allowing us to then decide if we could also recommend them to our clients.

In the “Forrester Wave™: API Management Solutions, Q4 2018” report, there is a comparison of many popular API management solutions. The report named WSO2 as one of the leading solutions and as most of its products are open-source we have therefore included an assessment of WSO2.

In addition, we have chosen to evaluate the GraphQL stack, which is an emerging data query and manipulation language. GraphQL currently has many adopters, who have started development of their APIs using this new architecture style. Some of our clients have also evaluated GraphQL for their use cases, so we already know that there is strong real world demand for this architecture style.

WSO2 vs GraphQL

WSO2

WSO2 API Manager is a solution for end-to-end API management in the cloud, on-premise, or in hybrid environments. In our research we’ve focused on the latest version of WSO2 API Manager, which is 3.0.0. and was released several months ago. It consists of six main components: API Publisher (admin portal), API Developer Portal (user portal), API Gateway, Key Manager, Traffic Manager and API Analytics.

Even though WSO2 API Manager is an open source product, it offers several pricing options: an open-source version, subscription-based (with an ability to update products with bug-fixes), and a cloud version. We’ve focused here on the open-source version.

WSO2 API Manager 3.0.0 architecture (https://apim.docs.wso2.com/en/3.0.0/)

GraphQL

GraphQL is an open-source query language for APIs that includes a server-side runtime for executing queries over types and fields. These are defined in schemas. It’s commonly  compared to REST, as both of these architectures provide ways to develop web APIs.

The GraphQL API is represented as a single endpoint, which is served over HTTP. Clients have the ability to define the exact structure of the data they need in a request query, so the amount of data transferred between the client and GraphQL server is lower compared to REST. The response is usually returned in a JSON format.

GraphQL has a specification for a query language and an execution language that describes capabilities and requirements of data-models for client server apps. It includes many spec implementations written for different languages, so users can choose the one that best suits their needs.

We’ve used Apollo as an example of one of the popular GraphQL specification implementations. This product is maintained by the dedicated Apollo team.

Apollo Platform includes a production-ready GraphQL server (Apollo Server), schema management and monitoring tool (Apollo Graph Manager) and client (Apollo Client). It also includes Apollo Gateway, which is a special configuration of Apollo Server designed to compose distributed GraphQL schemas.

https://www.apollographql.com/docs/intro/platform/

Apollo Server is a spec-compliant JavaScript GraphQL server that can be used by any GraphQL client. It’s main goal is to validate and execute queries by using a type system that is defined in schema.

Apollo Graph Manager is a cloud service that helps to manage, validate, and provide some security features on data-graph. Apollo Server pushes schema and analytics data into Graph Manager when this feature is enabled on the server. Graph Manager offers some basic free features and requires a subscription for others so please check their pricing model for more details.

Deployment structure

In order to check the main API management solution capabilities, we need to integrate them with some backend services. In our case we did our research based on the following architecture:


Here we have API Manager deployed in a separate K8S cluster. In the case of Apollo GraphQL Server, there is also the option to deploy it easily with Google App Engine. We tried both approaches.

API Manager solution is integrated with the backend services. In our case, we wanted to check several options within the integration including:

  • The standalone services, deployed as VM instances
  • The deployed services on the Google Kubernetes Engine cluster. This GKE cluster implements its services via the Ingress controller
  • With the Istio based services deployed on the GKE cluster  

The above backend services expose REST, SOAP, and WebSocket APIs. These APIs provide the ability to receive, update, and delete carts-related information based on user ID and item ID request parameters.

We also deployed Prometheus to check if we can collect and analyze any analytics data from the API Manager. And we’ve used Auth0 as an Identity Provider in order to check if API Manager can be integrated with a third-party service to support authorization/authentication.

WSO2 deployment details

WSO2 API Manager can be deployed in a containerized environment. There is a WSO2 docker registry where WSO2 applications images are kept. At the time of writing this article, WSO2 had one sample k8s deployment manifest for the 3.0.0 version, with the deployment split between WSO2 API Manager, API Analytics, and MySQL backend pods. However, we will most likely require a higher level of service isolation on production, so the configuration may need to be adjusted.

Apollo GraphQL deployment details

We used Apollo Server as a gateway to our backend services. Deployment was done using Google App Engine.

Initially, we had to use apollo-server-express as Apollo Server:

const { ApolloServer } = require('apollo-server-express');


Create app.yaml, which is required by Google App Engine:

runtime: nodejs
env: flex
service: carts-graphql-gateway
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10
automatic_scaling:
  min_num_instances: 1
  max_num_instances: 1
  cool_down_period_sec: 60
  cpu_utilization:
    target_utilization: 0.80

Set required engines field in package.json file:

"engines": {
 "node": ">=10.0.0",
 "npm": "6.x"
}

In order to build the GraphQL API, several basic steps should be performed:

1.  Build a schema

The schema is a major component of the graph API. It’s a blueprint that describes all of the data types and their relations. It also describes ways in which the clients can fetch data (queries) and how clients can modify data (mutations).

A simple model for our REST service would be as follows:

type Item {
   id: String
   itemId: String!
   quantity: Int
   unitPrice: Float
}

input ItemInput {
   id: String
   itemId: String!
   quantity: Int
   unitPrice: Float
}

scalar JSON

type Query {
   getItem(customerId: String!, itemId: String!): Item!
   getItems(customerId: String!): [Item]!
  }

type Mutation {
   addItem(customerId: String!, item: ItemInput!): Item!
   deleteItem(customerId: String!, itemId: String!): JSON!
}

2. Write data sources

Apollo Server is supposed to fetch data from any data source such as REST endpoints, gRPC services, databases, etc. DataSource is a class that’s responsible for fetching data from any backend. It also includes logic for caching and deduplication. There are some common datasource implementations in Apollo libraries for example, clients may use apollo-datasource-rest library, which provides RESTDataSource. For our example, we extended it to implement REST calls to our backend:

class CartsAPI extends RESTDataSource {
   constructor() {
       super();
       this.baseURL = propertiesFile.get("carts.service.url");
   }

   async getItem(customerId, itemId) {
       return this.get(`carts/${customerId}/items/${itemId}`);
   }

   async getItems(customerId) {
       return this.get(`carts/${customerId}/items`);
   }

   async addItem(customerId, item) {
       return this.post(`carts/${customerId}/items`, new Object({...item}));
   }

   async deleteItem(customerId, itemId) {
       return this.delete(`carts/${customerId}/items/${itemId}`);
   }
}

3. Write resolver

Resolver is responsible for fetching data (using data sources). It provides the instructions for turning GraphQL operations into data.

Query: {
   getItem: async (_, { customerId, itemId }, { dataSources }) =>
       dataSources.cartsAPI.getItem(customerId, itemId),

   getItems: async (_, { customerId }, { dataSources }) =>
       dataSources.cartsAPI.getItems(customerId),
},

Mutation: {
   addItem: async (_, { customerId, item}, { dataSources }) => {
                 return dataSources.cartsAPI.addItem(customerId, item);
        },

   deleteItem: async (_, { customerId, itemId }, { dataSources }) => {
           return dataSources.cartsAPI.deleteItem(customerId, itemId);
         },
}

API Manager capabilities check-list

We’ve defined several features that will help us perform our research and understand what is supported in the products that we’ve chosen for evaluation:

In addition, there are some useful facts related to specific API Manager solutions, which we will go into in more detail after evaluating the items in the above list.

Now let’s start with our first requirement for API Manager and check if WSO2 and Apollo Platform can help us with its implementation.

Presence of user and admin portals

In using the term “user portal”, we are referring to some kind of UI that enables users to find available APIs and evaluate and subscribe to them. While the term “admin portal” also refers to a UI, in this case we are referring to the ability to publish APIs and specify different limitations such as rate limits or security checks.

WSO2

WSO2 uses its own terminology for user and admin portals. For its user portal, WSO2 API Manager provides Developer Portal, which allows API creators to host and advertise their APIs while allowing API consumers to self register, discover, evaluate, subscribe to, and consume APIs.

As an admin portal, WSO2 offers API Publisher, which allows API creators to develop, publish, scale, monetize, and version APIs.

Apollo GraphQL

Apollo Platform has fewer capabilities here. It provides only limited admin portal functionality in Apollo Graph Manager such as GraphQL schema overview, usage info, etc. It’s important to note that it isn’t safe to use as a user portal, as currently all members in an organization have full permissions set. This means that all users have the ability to remove schema for example, which isn’t a secure solution for a user portal.

Conclusion

With regard to user and admin portals, WSO2 API Manager has rich functionality. It contains both Publisher and Developer Portal, each with their own range of capabilities. Apollo GraphQL only contains Graph Manager, which is responsible only for several capabilities of admin portal however, there is no portal for API clients.

Support for different backend API implementations

Here we are analyzing if API Manager solutions are able to integrate with different types of backend APIs. We expect to see support for the most popular protocols, i.e. REST, SOAP, and WebSockets.

WSO2

WSO2 API Manager supports the following types of backend API - REST, SOAP, WebSocket, and GraphQL. In the case of WebSocket, STOMP is not supported. All types of APIs can be restricted for access by roles in Publisher and Developer Portal.

WSO2 API Publisher provides two variants for creating APIs:

  • Manual API description - can be used in REST and WebSocket APIs
  • Generation of APIs based on backend API Specification - can be used in REST (OpenAPI/Swagger), SOAP (WSDL), and GraphQL (GraphQL SDL schema) APIs.

The second variant is preferable as there is no need to manually describe all available backend resources. API Specification can be loaded from the provided URL as well as directly from the schema file.

It is notable that WSO2 API Manager provides two options during SOAP API creation - Pass Through and Generate REST APIs. In the case of Pass Through, WSO2 exposes the SOAP API and will route all requests to the SOAP backend. The Generate REST APIs option allows for the exposure of legacy SOAP backends as the REST endpoints.

Apollo GraphQL

As we already mentioned, corresponding data sources should be used in order to fetch data from the backend. For the REST backend, Apollo provides apollo-datasource-rest library, clients just need to extend the already implemented RESTDataSource.

For the SOAP backend, there is no official library. Clients can try to use a third-party implementation, apollo-datasource-soap is an example.

As for the websockets, in general GraphQL supports websocket protocols via subscriptions. However, official Apollo Graph Manager documentation points out that in the case of clients using Graph Manager, subscriptions should be disabled in Apollo.

Conclusion

As you can see, WSO2 API Manager provides a larger range of backend API implementation support and expanded capabilities such as support of API specification. For GraphQL only the REST backend is supported out-of-the-box. For all other APIs, the dev team will need to write their own libraries or find third-party alternatives.

Support of FaaS (Serverless) components

In this part of the research we wanted to check if current API Manager solutions support FaaS components as a backend service.

WSO2

In WSO2 API Manager documentation there is no information about FaaS as a backend service support. However, there are some workaround solutions that can solve this problem. This involves creating a separate backend API that can invoke the lambda function and publish it. Alternatively, it is possible to create a custom Message Mediation sequence in WSO2 API Manager and set this sequence to request flow for the definite API in Publisher.

Apollo GraphQL

In the case where a GraphQL datasource needs to call a cloud function, there is no special logic for that process. Instead, you need to write a datasource that can send the HTTP request to the trigger function. For some cloud providers, tools exist for better integration for example when clients use AWS Cloud with AppSync, they can use built-in support for Lambdas as a datasource.

Conclusion

Regarding FaaS (Serverless) components, there is no out-of-the-box support for this kind of service in either API Manager solutions. However, there are some workarounds that can be used to effectively address this issue.

Service discovery

In this part of the research, we wanted to understand what the options were for the integration of API Manager with backend services. For example, do we need to define each endpoint location manually or is there some form of automation tool that can help to locate available services?

WSO2

When a new API is created in WSO2 API Publisher you need to define the backend endpoint (or endpoints) of the corresponding services. In WSO2 there are several ways in which this can be performed:

  • Use a real service host/port. In cases where a service address is changed, API Manager needs to be changed as well
  • Where services are deployed using Kubernetes, you can specify it’s Ingress controller name in a dev API Publisher, so Ingress can route all requests to the right services based on the request path
  • WSO2 provides the ability to discover services with the use of etcd in cases where you are using WSO2 microgateways
  • In the 3.0.0 version, a new feature was introduced making it possible to publish new APIs automatically using Kubernetes Operators. Please refer to ‘WSO2 Integration with K8S and Istio’for additional details on this feature.

Apollo GraphQL

As we discussed previously, the definition of services should be implemented directly in the code. Therefore, there is the option of using a real service host/port or Ingress controller name, with the decision being based on the nature of the deployment infrastructure.

Conclusion

Both API management solutions offer the ability to define services via real endpoint addresses or by using Ingress Controller service discovery capabilities. Additionally, the latest version of WSO2 provides the ability to automatically publish new APIs by utilising an integration with Kubernetes Operators.

API contract validation and enforcement

For this part of the research, we were looking to understand what kind of contract validations were supported by API Manager solutions. For example, if API Manager checks if new versions of the API have broken backwards compatibility.

WSO2

WSO2 API Manager provides the ability to validate API schema. Validation occurs at the time of schema import. This validation is relevant only to the specification rules (e.g., the OpenAPI definition is validated in accordance with the OAS 3.0 specification), and not related to the changes in the API during new version creation. All versions of the API are independent of each other. Regarding version control, API Lifecycle manager is very useful as it helps to control the state of different API versions.

Apollo GraphQL

GraphQL’s best practice is to avoid API versioning, which we usually use for regular REST-based APIs. The main point here is that clients read only those fields, which they have defined in a request, rather than the entire schema. In this case, most changes such as adding new fields won’t break clients.

However, some changes in schema such as field renaming or removal or a change in a field’s nullability will result in a breaking change in the GraphQL API as well. Therefore, there needs to be a mechanism in place to identify those breaking changes and notify the dev team about potential issues. Apollo Platform suggests using Apollo Graph Manager to track schema changes and report if something new may break clients.

Graph Manager generates differences between local schema and the one most recently registered. Note however that Graph Manager uses Graph Manager Analytics (which requires a paid subscription) to determine whether new changes affect queries/mutations that were executed on graph recently (the time window is customizable). It doesn’t compare two schemas entirely. So if a field wasn’t requested for some time, there is a chance that it’s changes won’t be reported by Graph Manager. Graph Manager then returns non-zero exit code if breaking changes were found. This means that this check can easily be integrated with CI.

Conclusion

WSO2 API Manager doesn’t compare previous and new versions of APIs. Therefore it won’t report if a new version contains breaking changes. However, it has the ability to validate API schema in accordance with some common rules when the API is created.

GraphQL doesn’t use versioning but Apollo Platform provides a mechanism to analyze schema changes and report if something is broken. This feature must be integrated with  Apollo Graph Manager, which requires a paid subscription.

Adapter service

In our research, use of the term “adapter service” refers to the functionality or possibility of getting a combined response from several backend services. It also refers to the ability to apply transformations so that we have only one public facing endpoint and can shield clients from excessive backend complexity.

WSO2

In WSO2 API Manager there are several options for implementing an adapter service:

  • Message Mediation - create XML or Java Mediators for request, response, and fault flow for a specific API in Publisher using the Runtime Configurations section. However, it is recommended to use the Message Mediation Java Class only when there is no built-in mediator that already provides the required functionality in XML
  • Ballerina language - create the Adapter Service using the Ballerina language (WSO2 open-source programming language) and deploy with Microgateway.

It means that there is only one way to create the Adapter Service directly in API Manager - by using the custom Message Mediation sequence. In this case, there is also a need to create separate APIs in Publisher and add the created flows in the Message Mediation panel. This Adapter API is versioned, updated, and maintained as a common API.

With regards to Message Mediation, it is impossible to get information from xml in the Publisher UI. This means that you won’t be able to properly understand the flow of the Adapter from the UI. In addition, it’s important to note that Message Mediation will be applied to ALL resources from the API. All requests to the current API (regardless of the kind of resource) will follow this mediation sequence.

Apollo GraphQL

One of the main advantages of GraphQL is that clients can compose any request query that they need with all the required fields. GraphQL then fetches data from the underlying services and composes one response to the client. There is no need to write any special adapter service to compose the backend services into a single API.

Conclusion

In Apollo GraphQ, the Adapter Service functionality works naturally, as it is one of the core features of this technology. As for WSO2, it isn’t a convenient solution to write the adapter in xml files, or even using Java classes. It may also be problematic to debug it in case of any issues. So for WSO2, it appears to be more suitable to write a separate service, which will then act as an adapter.

Usage audit and monitoring

We expected that the API Manager solution would provide useful API usage audit information such as API usage statistics, API response time, API usage by users, API subscriptions, etc. We also wanted to check how easy it would be to integrate the API Manager with a third-party monitoring system, which in our case is Prometheus.

WSO2

In the WSO2 eco-system there is an API Manager Analytics application that is responsible for usage auditing. It includes various groups of statistics including API Publisher statistics (general information such as the number of API calls, total API count, top API creators, etc.), API Developer Portal statistics (number of application calls, faulty calls per application, etc.) and Admin Portal statistics (availability of APIs). Almost all metrics are related to the different statistics of API calls. WSO2 API Manager offers an ability to configure alerts based on collected statistics.

WSO2 API Manager additionally provides audit logs. They are enabled for user actions in Publisher, Developer Portal, and Carbon (sign-in, sign-up, API and application modification, etc.). Management Console can also be useful for monitoring purposes through the use of JVM Metrics (CPU, Memory, etc.).

What about integration with third-party monitoring systems? As discussed above, we assessed the capability for WSO2 API Manager integration with Prometheus. There are two steps that need to be undertaken to achieve this purpose. The first step is running Prometheus JMX exporter as a java agent for WSO2 API Manager. By default, all WSO2 products expose JMX MBeans during the startup. The related service URL should be used as a target that exposes JMX MBeans to the Prometheus server. The second step is the definition of the JMX exporter endpoint in Prometheus config.

The largest component of the metrics that can be found in Prometheus using API Manager are related to API Manager as a Java application. There are also some types of metrics related to API calls however, API Manager Analytics is more suitable for providing a wider range of other metrics.

Apollo GraphQL

Apollo Graph Manager provides information on performed queries, requests, and errors. To view these metrics Apollo Server needs to be configured to connect to Graph Manager. It is possible to view some common performance metrics including request rate and request latency but it’s important to note that the GraphQL API is represented as a single endpoint, so all those metrics will be shown for the entire endpoint. It’s also important to emphasize that Apollo Graph Manager is a paid product, and many of its major functionalities are available only under a subscription.

In cases where the client needs detailed information on a specific query execution, Apollo Graph Manager can use operation traces to provide additional performance metrics such as:

  • Identifying the operations that are being executed
  • Identifying the clients that are executing each operation
  • The parts of the schema with the highest usage
  • Identifying which of the resolvers in the server are acting as bottlenecks

It is also possible to segment metrics by clients. To achieve this, each request should contain corresponding HTTP headers. This helps to analyze data more granularly. In particular it allows you to better understand if a high failure rate for an operation is tied to a specific client version.

Regarding integrations with third-party monitoring systems, it’s possible to publish basic Node JS app metrics. Using Prometheus as an example, this can be done using the express-prometheus-middleware library. Then metrics like GraphQL server CPU usage, or average request duration can be enabled on Prometheus dashboards. As a result, the combination of Graph Manager and third-party monitoring systems provides a good outcome.

Conclusion

Both API Manager solutions provide the ability to execute usage audit monitoring for a range of graphs and metrics. However, there are some key differences with their respective approaches. WSO2 API Manager divides these metrics into separate APIs, while Apollo GraphQL bases their metrics on whole schema. It is possible to make integrations with third-party monitoring systems for both solutions. It is also important to note that the metrics provided via Apollo Graph Manager require a paid subscription.

Authentication/role-based authorization

We wanted to understand the capabilities of securing APIs using authentication/role-based authorization processes. We also wanted to check if it was possible to integrate with a third-party authentication server, which is in our case was Auth0.

WSO2

WSO2 API Manager offers several types of application level security - OAUTH2, Basic, and Api Key. Specification of these types happens in API Publisher. There is the option to choose from several types of security level. In Developer Portal you can choose which type of access token will be supported by the application, OAUTH or JWT. The following grant types are supported in Developer Portal - Refresh Token, SAML2, Password, Client Credentials, IWA-NTLM, and JWT.

In WSO2 API Manager it is possible to define the scope for separate API resources. Scope presents a collection of user roles, which permit access to the specific resource. In this case, generation of the access token should be done by detailing specific roles. If there is a need to change the scope for some kind of resource in the API that is already being consumed in the application, the new scope-policy will work only after the caching period (relates to Key Manager cache).

When integrating WSO2 API Manager with a third party authentication server, WSO2 Identity Server should be used. It is an open-source identity and access management product that works as separate server. This product takes the role of Key Manager for API Manager.

What about compatibility of Identity Server with API Manager 3.0.0? Only the 5.9.0. version of Identity Server can be used with the 3.0.0. version of API Manager. In our case, we needed to use the prepackaged WSO2 Identity Server as a Key Manager (version 5.9.0.). It comes with the necessary configurations already installed that are needed to connect with WSO2 API Manager and is different to the default version of WSO2 Identity Server 5.9.0.

It’s necessary to set Identity Server as a Key Manager for API Manager and configure databases for API Manager and Identity Server (WSO2AM_DB and WSO2SHARED_DB should be common for both instances). A description of API Manager Gateway should also be added to Identity Server and the URL defined for Identity Server in the API Manager configuration.

The next step is to directly integrate with the third-party authentication server (in our case - Auth0 server). This requires the following steps:

  • Create Auth0 Identity Provider as a Federated Authenticator (with default OpenID connect) in Identity Server Carbon UI
  • Specify the Service Provider as a Federated IdP (in our case Service Provider is an application from Developer Portal).

What was the final outcome of this process? We integrated WSO2 API Manager with the Auth0 server using Identity Server (Authorization code was used as a Grant Type). However, we encountered a problem. This workflow works only with OAUTH token as a token type for application in Developer Portal. When we try to use the JWT token type, we always receive an Unclassified Authentication Failure error without any further description. Unfortunately, we weren’t able to find information on how to fix this problem in WSO2 documentation.

Apollo GraphQL

Apollo authentication and authorization should be implemented directly in the code. Therefore we wanted to check what needed to be done to integrate Apollo Server with Auth0, authenticate clients based on their credentials using OpenID Connect protocol, and authorize access to API based on roles.

GraphQL documentation says that we can use Express middleware to add an authentication layer between the GraphQL client and server. The access token should be passed by the client as a specific request header. It can then be validated in the middleware and the authentication data will be set in the request object to pass to the next layers.

Below is an example of the code where we have added token validation (it’s performed by Auth0). If the check passes, then we decode it and place it into context. In the case where the validation isn’t successful, then clients will get a 401 Error. Context is created for each request, so it’s safe to keep such sensitive information there. The context object can be accessed later in code for additional checks:

const server = new ApolloServer({
   typeDefs,
   resolvers,
   context: ({ req }) => ({
       token: jwtDecode(req.headers.authorization),
   }),
   dataSources,
   tracing: true,
});

const jwtCheck = jwt({
   secret: jwks.expressJwtSecret({
       cache: true,
       rateLimit: true,
       jwksRequestsPerMinute: 5,
       jwksUri: process.env.AUTH0_JWKS_URI
   }),
   audience: process.env.AUTH0_IDENTIFIER_URI,
   issuer: process.env.AUTH0_DOMAIN_URI,
   algorithms: ['RS256']
});

As for the authorization, GraphQL documentation says that there are only two places where authorization logic can be placed:

  • Resolvers:
addItem: async (_, { customerId, item}, { dataSources }) => {
   const permissions = dataSources.cartsC1API.context.token.permissions;

   if (permissions.includes(propertiesFile.get("carts.service.modification.permission"))) {
       return dataSources.cartsAPI.addItem(customerId, item);
   } else {
       throw new Error("You a not authorize for modifying  items");
   }
}
  • Business logic layer

In the case where a user doesn’t have permission to view the resource, the status code of the response will be 200. Information about errors will be placed in the response body.

It’s not recommended to use resolvers in GraphQL best practices. Instead, it is suggested to use it only for prototyping and all related logic should be moved to the business layer.

The Apollo documentation outlines several additional authorization techniques:

  • On model level - It’s recommended to move fetching and transformation logic from resolvers to centralized model objects. In this case, authorization can also be performed there
  • Authorization using custom directives - In such a case, the @auth directive can be either be placed directly into the GraphQL schema by field or type
  • Pass headers to backend services to delegate all security checks there

As you can see, there are several potential options available and GraphQL and Apollo only outline suggested best practices. It is up to the developers to select the option that best suits them.

Conclusion

WSO2 API Manager includes different built-in capabilities to secure the API with authentication/role-based authorization. It’s also possible to integrate WSO2 API Manager with third-party authentication servers. In the case of Apollo GraphQL, authentication and authorization logic should be implemented by developers directly in the code.

Requests throttling

There needs to be a way to enforce agreement on API usage. One of the parameters is rate limits for the number of API calls that users can make. Those limitations can be set on different levels and with different rules.

WSO2

In WSO2 API Manager there are four defined levels of throttling policy configurations:

  • Application-level policy - number of requests that can be sent to an application per access token
  • Subscription-level policy - number of requests that can be sent from an application to the API
  • API-level policy - number of requests that can be sent to the API (there is the option  to specify the throttling policy for the API generally or from separate resources)
  • Backend throughput policy - number of requests that can be sent to the backend service

WSO2 API Manager provides the option to create custom throttling policies in Admin Portal.

Apollo GraphQL

With the GraphQL API, it can be a difficult task to configure rate limits on any level other than the entire GraphQL endpoint. As there is no official GraphQL or Apollo library to perform this rate limiting, the dev team should look at third-party projects such as  express-rate-limit, or implement their own frameworks. In cases where rate limits need to be added more granularly, at the resolvers level for example, then graphql-rate-limit project can be used.

Conclusion

WSO2 suggests different levels at which rate-limits can be configured and this functionality is provided out-of-the-box. In contrast, Apollo doesn’t have built-in capabilities for rate limiting so the dev team should use third-party libraries, or alternatively write their own.

WSO2 Integration with K8S and Istio

This part of the research is related only to WSO2 API Manager and describes one of its features.

In WSO2 API Manager version 3.0.0., a new feature was released - Kubernetes Operator for APIs. You can now deploy an API for individual services using Kubernetes. This API will act as the microgateway for related services, providing security, throttling, tracing, logging, and analytics capabilities. Using Operator for APIs you can also publish those APIs to the developer portal automatically, there is no need to create the APIs manually.

As with any other Kubernetes cluster, WSO2 API Manager can work with Istio. You can manually enable/install Istio in the WSO2 API Manager cluster to manage traffic routing, limitations, and security. However, WSO2 API Manager has native integration with Istio service mesh, meaning there is a separate WSO2 API Manager distribution with Istio integration.

In this type of deployment, Istio provides data plane and control plane capabilities, while WSO2 API Manager provides management plane capabilities to manage microservices. When a new API is published via API Publisher Portal, the Portal pushes all related policies to the Envoy proxy via the Pilot and Mixer. The new API will then be available in WSO2 API Developer Portal, as usual. However, now clients access APIs not through the WSO2 API Gateway but by using the Istio Ingress gateway instead. It’s important to note that this approach may soon be changed however as there are discussions in the Istio community about moving away from the Mixer and Mixer plugin concept. As a result, WSO2 is currently working on an alternate strategy.

Alternative Apollo GraphQL Server deployment strategies

The standard API Manager deployment is detailed at the start of this article. In this next section, we will assess Apollo GraphQL deployment in more detail as there are some interesting deployment characteristics that only relate to Apollo GraphQL.

Serverless deployment

Let’s look at deployment of Apollo Server as a serverless, autoscale GraphQL API to the cloud. Apollo Platform has support for both AWS lambdas and Azure Functions. As for Google Functions, there are also several deployment options:

  • Replace the standard apollo-server-express server to apollo-server-cloud-function
  • Use the serverless-http module that allows wrapping GraphQL API for serverless use
  • Use Google Cloud Functions with Firebase

For almost all options (with the exception of serverless-http), we’ll need to replace the standard Express server with a cloud-provider specific one. In this case, we’ll need to think about how to migrate logic that was done in Express middleware.

Deployment with K8s and Istio

In comparison with standalone deployment types like Google App Engine or Google Functions, container orchestration with service mesh can provide some additional features that are not available in Apollo out-of-the-box.

For example, Apollo server doesn’t have built-in capabilities for circuit breaking in its data sources. However, Istio provides traffic management features that can be helpful upon deployment and production use such as circuit breaking and service timeout management. You can craft destination rules to limit the number of simultaneous or pending connections to eliminate service overloads and failures.

Traffic shifting and traffic mirroring can be helpful for service version upgrades. New versions can be deployed and tested so traffic can be switched to new deployments. It is also possible to use JWT based authentication either with Auth0 or another suitable provider. There is no need to insert any authentication code into the Apollo server code because everything can be handled by Istio services after adding special authentication policies.

Below is an example of this kind of deployment:

It is a good idea to use Apollo Platform in conjunction with service mesh. This is because  this can provide additional functionality that isn’t supported by Apollo itself, but may be important for production deployment.

Conclusion

Below is a summarised comparison of WSO2 API Manager and Apollo GraphQL based on our research and experience:

Point of comparison WSO2 API Manager Apollo GraphQL
Presence of user and admin portal ❌ - some capabilities can be found in Apollo Graph Manager (paid product)
Support of different backend API implementationse REST, SOAP, WebSocket, GraphQL. Also includes support of API specifications - OpenAPI/Swagger, WSDL, GraphQL schema Out-of-the-box only REST and GraphQL. Only GraphQL schema is supported as an API specification (in Apollo Gateway)
Support of FaaS (Serverless) components ❌- however, there are some workarounds ❌- however, there are some workarounds
Service discovery Manual host/port or Ingress controller address specification, automatically publish new APIs via integration with Kubernetes Operators Manual host/port or Ingress controller address specification
API contract validation and enforcement ❌- all API versions are independent from each other ❌- supported in Apollo Graph Manager however only in paid version
Adapter service ✅ - this is a major feature of GraphQL
Usage audit and monitoring ❌ - this capability exists in Apollo Graph Manager however only in paid version
Authentication/role-based authorization ❌ - needs to be implemented by developers
Requests throttling ❌ - needs to be implemented by developers
Documentation and ease of use Only general information is provided in the documentation. Can be hard to configure to suit specific use-cases that don’t correspond to out-of-the-box functionality. Documentation contains a description of only some API Manager features. Many API Manager features need to be implemented through the code.


WSO2

WSO2 is one of the few vendors that provides both open source and paid versions of API Manager. The paid versions include a subscription as well as a cloud version. The open-source version allows organizations to use API Manager at no cost and our research indicates it still maintains a range of useful functionalities.

It should be noted that although we were able to perform most of the defined tasks using the open-source solution, we still encountered some problems for which it was difficult to find detailed solution information on. The WSO2 documentation has fairly generic information only, such that it’s difficult or impossible to find detailed information for any special tasks that need to be performed. We therefore had to spend a large amount of time working out how to integrate with a third-party Authorization server or to find out the best way to create an adapter service.

Some compatibility problems were also encountered between different WSO2 products and versions. For example, we started our research with WSO2 APIM 2.6.0,, which meant that it became difficult to then perform some tasks when the newest version was rolled out (in the 3.0.0. version, most of the configuration was migrated from xml files to one common toml file).

It is also important to note that clients won’t receive bug-fixes with the open-source version. Instead they will need to wait for the next major WSO2 version. The paid versions of WSO2 API Manager can solve many of the above mentioned challenges as it provides the WSO2 Update Manager, which allows for product updates with bug-fixes. It also includes the ability to migrate to new versions of WSO2 products smoothly and most importantly, provides support from the WSO2 team, which can be very helpful for cases where your task is not described in any official documentation.

Our overall conclusion is that WSO2 API Manager is a good product however, using the open-source version can result in running into a range of problems. As a result, the dev team will likely need to spend more time familiarizing themselves with all the required WSO2 products and be prepared to try and resolve various tricky tasks on their own.

Apollo GraphQL

GraphQL is a query language and it’s main usage is to build “one-size-fits-all” style APIs that are convenient for all API clients. However, in our research we were also interested in analyzing whether it might possible to provide additional API Manager capabilities in addition to its great query language and query execution capabilities. We chose the Apollo Platform as it is one of the most popular GraphQL implementations. It includes Apollo Server, Apollo Gateway as well as some interesting tools such as Apollo Graph Manager.

In general, we determined that the Apollo Platform does provide some of the necessary features that we were looking for in an API Manager solution such as API contract validation, usage audit and monitoring, and admin portal. However, for each of those features, clients will have to use the subscription-based Apollo Graph Manager.

All authentication/authorization requirements should be implemented by the developer team. Similarly, with regards to regular NodeJS application, there is no additional support from the platform. For other special requirements such as rate-limiting, these should be developed from scratch, with particular attention given to careful design. There are no official libraries for such tasks, so each team needs to write their own internal tools.

Subscribe to our latest Insights

Subscribe to our latest Insights