There are many pros and cons for both GraphQL and REST APIs, but one of the areas where GraphQL really shines is API composition. Taking data from multiple APIs and combining them to make something new is a key part of delivering a useful service.
Today, we're going to take a look at StepZen, a product that allows you to build GraphQL APIs composed of REST, Database, and other GraphQL sources. We'll use it to build an API endpoint that shows the price of an item in a user's local currency based on their IP address. GraphQL remains an emerging technology, and adoption is still lagging behind RESTful APIs. Kong provides the degraphql plugin which allows us to convert the GraphQL API we build with StepZen back into a REST API, which may be more comfortable for users of our API.
API Composition with StepZen
StepZen provides a GraphQL studio that helps you build and deploy your own GraphQL API by combining prebuilt APIs such as Accuweather, Airtable, GitHub, SpaceX, Trello, and more. In this example, we're going to combine IP-API (to convert an IP address to a geolocation) with the Frankfurter API (an exchange rate API). GraphQL studio helpfully provides some prebuilt queries to help us understand how these APIs work and how they can be combined.
The schema tab in GraphQL Studio allows you to see the data available from each API. I'd like to call your attention to the priceInCountry field in the IpApi_Location type. priceInCountry is defined as a materializer, which is a custom StepZen directive that acts like a function. priceInCountry takes arguments provided by the caller and combines them with the currency field in the current schema by calling the frankfurter_convertedAmount query to calculate a local price.
The materializer definition is included in the schema itself inside type Query, and uses JavaScript to call an API and transform the data:
frankfurter_convertedAmount(
amount: Float!
from: String!
to: String!
): Float
@rest(
cel:"""
function transformREST(s) { var data = JSON.parse(s)
let toCurrency = get('to')
let amount = get('amount')
let convertedAmount = (data["rates"][toCurrency]||1.00) * amount
return JSON.stringify(convertedAmount)
}"""
endpoint:"https://api.frankfurter.app/latest?from=$from" )
We're going to use this materializer to build a query that accepts an amount, source currency, and IP address and returns the identified country code and price in that country:
We'll walk through how to run this query in the next section, but first, we need to deploy our new API.
Deploying your API
GraphQL Studio is great, but it's not intended for production deployments. To ship our API, we need to import it as a data source into our own StepZen account using the CLI. The GraphQL endpoint URL is available in the top bar in GraphQL Studio.
To do this, we run stepzen import graphql to tell StepZen that we want to build a new API on top of an existing GraphQL API. This will generate some schema files locally based on the GraphQL endpoint URL that you provide.
stepzen import graphql
? What would you like your endpoint to be called? demo/converter
? What is the GraphQL endpoint URL? https://graphqldd.stepzen.net/api/dd1cf47f51ac830fe21dc00ec80cee65/__graphql? Prefix to add to all generated type names (leave blank for none)
? Add an HTTP header, e.g. Header-Name: header value (leave blank for none)
Starting... done
Successfully imported schema graphql from StepZen
Once the import completes, you can deploy your API to StepZen by running stepzen start. At this point you can visit http://localhost:5001/demo/converter to test your deployed API using the locally running StepZen query explorer. Paste the query definition above into the main editor section, and then paste the following into the Query Variables editor:
{"amount":100,"from":"GBP","ip":"8.8.8.8"}
Submit your request and you'll see a response in the right-hand pane that looks like this:
However, if I visit that URL I can see that my requests need to be authenticated. We want to make this a public API, but only if it's accessed through our API gateway. We can automatically add an authentication header, but first, we need to run Kong Gateway.
Running Kong Gateway
The quickest way to get started with Kong Gateway is to run the following command (you'll need docker installed):
curl -Ls https://get.konghq.com/quickstart | sh -s -- -i kong-gateway
This will create two Docker containers – a database to store configuration and Kong Gateway itself. Once you see the "✔ Kong is ready!" message, we can configure a route that proxies requests through to StepZen.
> Port 8001 is the administration port for Kong Gateway, while port 8000 is used to proxy requests to their destination
If you now call curl localhost:8000/price you'll see the same 401 Unauthorized error that we saw when calling the API directly.
Automatic API Authentication
Now Kong Gateway is proxying requests to our StepZen API, we can automatically add authentication credentials to requests flowing through the gateway. We'll use the Request Transformer plugin in Kong to add the `Authorization` header to the incoming request before forwarding it to StepZen.
First, run stepzen whoami –apikey to fetch your StepZen credentials. Configure the Request Transformer plugin with the StepZen key using the config.append.headers setting:
At this point, we're using Kong Gateway to proxy requests to StepZen and add authentication. It also means it's easy to add any other plugin to protect your API as the number of requests grows.
Everything we've done up until now can be done with the free version of Kong, but we're about to move on to some enterprise features. If you want to code along, make sure to apply your license to your locally running instance:
export KONG_LICENSE_DATA='{"my":"license"}'
curl -X POST localhost:8001/licenses -d payload=$KONG_LICENSE_DATA
Convert GraphQL to REST
As I mentioned earlier, our existing customers are used to consuming REST APIs and aren't too familiar with how to write GraphQL queries. In order to keep things simple for them, we'll use Kong Gateway to convert our StepZen GraphQL API to a REST API using the degraphql plugin.
The degraphql plugin allows you to create traditional REST-based routing rules, map them to GraphQL queries, and forward the queries to a server. Before installing the plugin, we need to modify the existing graphql-demo service, setting the target URL to the domain-only portion of our StepZen URL.
Once this is done, we can activate the degraphql plugin on our service by providing the path to our demo endpoint in the graphql_server_path configuration option:
Once degraphql is activated, requests to our/price endpoint will return a 404 response rather than proxying to the upstream server. This is because we haven't mapped any REST requests to an underlying GraphQL query yet.
To map a path to a query, we can make a POST request to /degraphql/routes:
curl -X POST http://localhost:8001/services/graphql-demo/degraphql/routes \--data uri="/gbp/:ip/:amount" \
--data query='query($amount:Float!,$ip:String!){converted:ipApi_location(ip:$ip){countryCode price:priceInCountry(amount:$amount,from:"GBP")}}'
Note how the :ip and :amount entries in the uri parameter start with a colon. This means that the values in these segments will be passed into the query as named parameters. We can now make a normal GET request and watch as Kong makes a GraphQL request on our behalf:
Our customers can now interact with our upstream GraphQL endpoint as though it was a REST API, but there's just one thing about the response that's bothering me. GraphQL responses always contain a data key, but in our example, there's only a single key inside the data.
Let's use Kong's jq plugin to perform some post-processing on the response before responding to our caller. The jq plugin allows you to transform JSON data on request and response objects. We'll use a short jq operation to return everything inside the .data key:
We set out to compose an API from multiple different sources, then expose that as a simple REST endpoint for consumers. Using a combination of StepZen's materializers and Kong Gateway plugins, we've managed to deliver exactly what our consumers need without adding a single line of code to our application.
We're pleased to announce the launch of Standard Webhooks! Kong has been part of the Technical Committee of this standard with other great companies like Svix (the initiator of the project), Ngrok, Zapier, Twillio, Lob, Mux, and Supabase. This was
Modern software design relies heavily on distributed systems architecture, requiring all APIs to be robust and secure. GraphQL is no exception and is commonly served over HTTP, subjecting it to the same management concerns as any REST-based API. In
There are many different ways to deploy Kong Gateway. In this post, Viktor Gamov (Principal Developer Advocate at Kong) walks through the four most popular ways. Depending on your particular use case, you may find that one or more of these is a goo
Viktor Gamov
Centralized Kong Management with Active Directory/LDAP
Kong Enterprise provides customers with the fastest, most scalable and flexible API management solution in the market. One of Kong's main advantages is the ability to quickly deploy and integrate with a customer's ecosystem of already-deployed solut
Routing Tricks and Tips Kong is very easy to get up and running: start an instance, configure a service, configure a route pointing to the service, and off it goes routing requests, applying any plugins you enable along the way. But Kong can do a lo
Kong
Modernizing Integration & API Management with Kong and PolyAPI
The goal of Integration Platform as a Service (iPaaS) is to simplify how companies connect their applications and data. The promise for the first wave of iPaaS platforms like Mulesoft and Boomi was straightforward: a central platform where APIs, sys
Gus Nemechek
Insights from eBay: How API Ecosystems Are Ushering In the Agentic Era
APIs have quietly powered the global shift to an interconnected economy. They’ve served as the data exchange highways behind the seamless experiences we now take for granted — booking a ride, paying a vendor, sending a message, syncing financial rec
Amit Dey
Ready to see Kong in action?
Get a personalized walkthrough of Kong's platform tailored to your architecture, use cases, and scale requirements.