Easily restore your project to a previous version with our new Instant One-click Backup Recovery

Working with Hygraph as a Source for GraphQL Mesh

Extend and integrate your Hygraph project with other APIs, including GraphQL, OpenAPI, gRPC, Mongo, and more with GraphQL Mesh.
Jamie Barton

Jamie Barton

Aug 26, 2021
hygraph and graphql mesh

Imagine building a travel site that is packed with destinations visitors can explore to plan their summer vacation. While you'll want to show off the great amenities, and gorgeous views, you may also want to show details about the current weather.

One of the most spouted features of GraphQL is that it's a single endpoint for your data — that's fine if you're using one service for all of your data.

You'll most likely want to query hotel reviews and photos from your Content Management System (Hygraph), the current forecast using a Weather API (Weatherbit), and maybe flight prices from a flights API (Rapid) but doing this in one request isn't so straightforward — until now.

You could make requests to multiple APIs on the frontend, but you'll often find this adds complexity to those managing the frontend.

If you want to follow along — create a project with Weatherbit.io and a new Hygraph project using the "Travel Site" schema template.

undefined

Open the API Playground and run the following query:

{
hotels {
name
rooms
photos {
url
}
reviews {
content {
html
}
destinations {
name
description
}
}
}
}

You should see some example data we populated your project with when you created it from the schema template.

Now, if you imagine the following query:

{
hotels {
name
rooms
photos {
url
}
reviews {
content {
html
}
}
destinations {
name
description
forecast {
uv
weather {
description
}
}
}
}
}

You'll notice we are trying to fetch forecast on destinations, and if you try to run this within your project, you'll see it's not defined, and get an error.

You could create a model in Hygraph and keep a relation to forecast up to date, but this isn't scalable. Thanks to APIs we can handle this request programmatically.

#GraphQL Mesh

To query data across multiple remote APIs, we'll be using GraphQL Mesh.

You'll want to obtain an API key with Weatherbit and create a new project with Hygraph. You can select the "Travel site" project template to quickly scaffold a new project with example destinations.

Then, inside of a new folder for your project, create the file .meshrc.yml and add the following:

sources:
- name: Hygraph
handler:
graphql:
endpoint: YOUR_HYGRAPH_ENDPOINT
- name: Weather
handler:
openapi:
source: https://www.weatherbit.io/static/swagger.json
baseUrl: https://api.weatherbit.io/v2.0/current

ℹ️ Don't forget to replace YOUR_HYGRAPH_ENDPOINT with your project endpoint. If your API endpoint isn't public, you'll want to create a Permanent Auth Token, and update the Hygraph source:

sources:
- name: Hygraph
handler:
graphql:
endpoint: YOUR_HYGRAPH_ENDPOINT
operationHeaders:
Authorization: "Bearer YOUR_HYGRAPH_TOKEN"

Now, let's configure GraphQL Mesh to add a new field to our Hotel type (provided by Hygraph).

We can do this by providing additionalTypeDefs to our .meshrc.yml:

additionalTypeDefs: |
extend type Destination {
forecast: Forecast
}

Then we can provide additionalResolvers to our .meshrc.yml to connect the query to our "Weather" handler:

additionalResolvers:
- targetTypeName: Destination
targetFieldName: forecast
requiredSelectionSet: |
{
location {
latitude
longitude
}
}
sourceName: Weather
sourceTypeName: Query
sourceFieldName: getForecastDailyLatequalToLatLonLon
sourceArgs:
lat: "{root.location.latitude}"
lon: "{root.location.longitude}"
key: YOUR_WEATHERBIT_API_KEY
result: data[0]

ℹ️ Don't forget to replace YOUR_WEATHERBIT_API_KEY with your actual API key.


Inside of the resolvers above we declare Destination as our target type, and the additional type definition forecase that we want to create a resolver for.

The requiredSelectionSet is necessary because we need to fetch the latitude and longitude from the query we're executing — the root.

The sourceName is the source handler we declared above, in this case "Weather". We then declare the query that is to be ran against the "Weather" API — in this case getForecastDailyLatequalToLatLonLon.

To finish connecting the source of our additional resolver, we'll pass the latitude and longitude from the Destination model to the query arguments, along with our API key.


To start the server you'll want to run the custom dev script we wrote earlier, npm run dev.

Now, if we run the query from earlier, we'll get the following results:

undefined

{
"data": {
"hotels": [
{
"name": "Luxury Villa on the Volcano",
"rooms": 0,
"photos": [
{
"url": "https://eu-central-1-shared-euc1-02.graphassets.com/AvHQ3RDvFSousA8iwElOKz/DRyuTiY0Tblrkf2AgeMy"
},
{
"url": "https://eu-central-1-shared-euc1-02.graphassets.com/AvHQ3RDvFSousA8iwElOKz/gWkbJ8CERnmBonnqJVNP"
}
],
"reviews": [
{
"content": {
"html": "<p>Fusce eget ultricies quam, sollicitudin varius diam. Suspendisse ut massa vel velit sollicitudin facilisis vel facilisis augue. Praesent sodales finibus nibh sit amet faucibus. Nam faucibus diam vel arcu venenatis euismod. Morbi metus neque, porttitor in tincidunt ac, ultrices a elit. Mauris varius aliquet neque id viverra.</p>"
}
}
],
"destinations": [
{
"name": "Santorini",
"description": "",
"forecast": {
"uv": 6.18308,
"weather": {
"description": "Clear sky"
}
}
}
]
}
]
}
}

Great success! You can get the code for this example on GitHub.

Blog Author

Jamie Barton

Jamie Barton

Jamie is a software engineer turned developer advocate. Born and bred in North East England, he loves learning and teaching others through video and written tutorials. Jamie currently publishes Weekly GraphQL Screencasts.