Working with field resolvers and Fetch

Working with field resolvers and Fetch

Resolvers are a powerful way to extend your Grafbase backend with data from other data sources. We can use resolvers to compute custom business logic, make network requests, invoke dependencies, and lots more.

In this guide, we'll create a new GraphQL API using the Grafbase Database to store Places, and then with field resolvers fetch the current weather from OpenWeather.

Inside of a new directory or an existing project run the following command:

npx grafbase init

Open the file grafbase/schema.graphql and replace the contents with this schema:

type Location { latitude: Float! longitude: Float! } type Place @model { name: String location: Location }

Now run the Grafbase CLI to start your local development server:

npx grafbase dev

Next open http://localhost:4000 and add your first database entry using a GraphQL mutation:

mutation { placeCreate( input: { name: "Grand Hotel Central" location: { latitude: 41.3849706, longitude: 2.1755767 } } ) { place { id } } }

We'll begin by adding a new field to the Place model for weather that uses the return type Float and uses the @resolver directive:

type Place @model { name: String location: Location weather: Float @resolver(name: "place/weather") }

Now create the file grafbase/resolvers/place/weather.js and add the following:

export default function Resolver() { // ... }

Before we can make a request to get the weather we must first fetch the location data from the root object (Place):

export default function Resolver(root) { const { location } = root }

We mentioned previously that we will use OpenWeather to get the current weather data.

OpenWeather provides a free tier that we can use for the purposes of this guide.

Create an account and get your API key from your account settings:

API keys

Now add your API key to the file grafbase/.env in this format:

OPENWEATHER_API_KEY=

We can then use the environment variable inside the resolver with process.env:

export default function Resolver(root) { const { location } = root const apiKey = process.env.OPENWEATHER_API_KEY }

Now we piece together both the current location.latitude and location.longitude values with the OpenWeather API.

Let's first check everything is working as we expect and structure the API request visiting the URL below. It includes a random lat/lon value but you will need to insert your API key.

https://api.openweathermap.org/data/2.5/weather?lat=9.62570&lon=-16.51928&appid=OPENWEATHER_API_KEY

You should see a response similar this:

{ "coord": { "lon": -16.5193, "lat": 9.6257 }, "weather": [ { "id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d" } ], "base": "stations", "main": { "temp": 296.65, "feels_like": 297.12, "temp_min": 296.65, "temp_max": 296.65, "pressure": 1012, "humidity": 79, "sea_level": 1012, "grnd_level": 1012 }, "visibility": 10000, "wind": { "speed": 4.09, "deg": 349, "gust": 4.1 }, "clouds": { "all": 11 }, "dt": 1679579561, "sys": { "sunrise": 1679555323, "sunset": 1679599003 }, "timezone": -3600, "id": 0, "name": "", "cod": 200 }

The response temperatures are by default Kevlin, but we can change this to Celsius by adding &units=metric to the URL.

Now let's put all of this together (don't forget to replace the random lat/lon values) and add the request to the resolver function:

export default function Resolver(root) { const { location } = root const apiKey = process.env.OPENWEATHER_API_KEY if (!location) return null return fetch( `https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&units=metric&appid=${apiKey}`, ) .then(res => res.json()) .then(({ main }) => main.temp) }

For the purposes of this guide we'll only return main.temp from the resolver.

We're now ready to test everything out. We'll begin by adding a new Place to the Grafbase Database.

Start the Grafbase CLI:

npx grafbase dev

Then go to http://localhost:4000 and run the GraphQL mutation below.

Make sure to use the id for the place you created at the very beginning.

{ place(by: { id: "..." }) { name weather } }

That's it! You should see the current temperature in the response resolved using OpenWeather.

Get Started

Build your API of the future now.