Most of the time the data stored in a database is static. The data we put into the database is the data that we retrieve with our GraphQL query. But what about those times we need something a bit more dynamic? That is where we can leverage a solution like Dgraph Lambda to bring business logic directly into our GraphQL schema.
In this blog, we will go over a simple example of a calculated field. We will take an array of numbers stored in a field and return the average of that array. Although the example is not complex, it will show you the basics and give you a good foundation to build more complex logic using Dgraph Lambda.
You can check out the accompanying video for this article from our YouTube channel below:
For this first example, we will start extremely simple. What we will accomplish is taking a Float
array stored in the database and calculating the average of it. The average itself will not be stored in the database but will be returned through a GraphQL query as if it is. This will be transparent to the user and powered by Dgraph Lambda.
The GraphQL schema will look like this:
type Student {
id: ID
name: String!
grades: [Float]
gradeAverage: Float @lambda
}
This schema contains a Student type with a few fields. Notice the gradeAverage
field: we’ve annotated it with a @lambda
directive. The @lambda directive tells Dgraph that this field will get resolved by some custom JavaScript inside Dgraph Lambda.
In Dgraph Cloud, navigate to the Schema screen, add this schema to the textbox, and click Deploy. This will deploy the schema to Dgraph and get your GraphQL endpoint ready.
At this point, we need to create our custom logic within Dgraph Lambda that will power this field. For that, we will loop through all of the Float
entries in the array, add them together, and divide by the total number of entries to get the average. That logic will look like this:
const gradeAverageResolver = ({parent: {grades}}) => {
var total = 0;
for(var i = 0; i < grades.length; i++) {
total += grades[i];
}
return total / grades.length;
}
self.addGraphQLResolvers({
"Student.gradeAverage": gradeAverageResolver
})
In this logic, you’ll see that we have created a function called gradeAverageResolver
that gets the grades array from the parent type. It then returns the average of the grades.
In Dgraph Cloud, navigate to the Lambda screen, add in the above code, and click Save. This will make your Lambda go live!
Lastly, we add the resolver to the gradeAverage
field using the self.addGraphQLResolvers
function. This will bind this function to the field in the GraphQL schema.
With our logic and schema in place, we can now issue a mutation to add some data and bring back our calculated field in the return object. Here’s an example mutation to try out:
mutation MyMutation {
addStudent(input: {name: "Diggy McDgraph", grades: [65, 61.2, 72, 91, 99.9]})
{
student {
name
grades
gradeAverage
}
}
}
In Dgraph Cloud, navigate to the GraphQL screen, add the above mutation to the text area, and click the Play button at the top of the screen.
The response should look like this:
Congratulations! You just created your first calculated field in GraphQL using Dgraph Lambda! Now that you know the basics, you can dig further into our Dgraph Lambda docs and previous blogs containing more examples on Dgraph Lambda. When it comes to adding custom logic to your GraphQL endpoint, no solution is more simple than using Dgraph Lambda and JavaScript. Stay tuned for further blogs where we explore even more ways to build and customize logic in GraphQL services.