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 Place
s, 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:
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.