Table of Contents
- Introduction
- Prerequisites
- Setting Up
- Creating a GraphQL Schema
- Implementing Resolvers
- Handling Queries
- Handling Mutations
- Testing the GraphQL Server
- Conclusion
Introduction
In this tutorial, we will learn how to build a GraphQL server in Go. GraphQL is a query language for APIs that provides a more efficient and flexible alternative to traditional RESTful APIs. By the end of this tutorial, you will be able to create a fully functioning GraphQL server in Go.
Prerequisites
To follow this tutorial, you should have a basic understanding of Go programming language and have Go installed on your machine. You should also be familiar with the concepts of APIs and HTTP. Additionally, you should have a text editor or integrated development environment (IDE) set up for Go development.
Setting Up
First, let’s set up our Go project. Open your terminal or command prompt and create a new directory for your project:
mkdir graphql-server
cd graphql-server
Next, initialize a new Go module:
go mod init github.com/your-username/graphql-server
This will create a go.mod
file in the current directory. Now, we can start building our GraphQL server.
Creating a GraphQL Schema
The first step in building a GraphQL server is to define a schema. The schema defines the structure of the data that the server can query and mutate. It also specifies the available operations and their arguments.
Create a new file called schema.graphql
in the project directory and add the following code:
type Query {
hello: String!
}
schema {
query: Query
}
This schema defines a single query called hello
, which returns a string. The exclamation mark after String
indicates that the field is non-nullable.
Implementing Resolvers
Resolvers are responsible for executing the queries and mutations defined in the schema. They fetch the requested data and return the result to the client. Let’s create a new file called resolver.go
and implement the resolver functions:
package main
type Resolver struct{}
func (r *Resolver) Hello() string {
return "Hello, world!"
}
In this example, we created a struct called Resolver
, which will serve as the root resolver for our GraphQL server. We implemented a method called Hello
that returns the string “Hello, world!”.
Handling Queries
Now, let’s implement the code that handles queries. Create a new file called server.go
and add the following code:
package main
import (
"fmt"
"github.com/graphql-go/graphql"
"github.com/graphql-go/handler"
"net/http"
)
func main() {
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"hello": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
resolver := &Resolver{}
return resolver.Hello(), nil
},
},
},
}),
})
if err != nil {
fmt.Println("Error creating schema:", err)
return
}
h := handler.New(&handler.Config{
Schema: &schema,
Pretty: true,
GraphiQL: true,
})
http.Handle("/graphql", h)
http.ListenAndServe(":8080", nil)
}
In this code, we create a new GraphQL schema with a single query field called hello
. We provide a resolver function that creates an instance of our Resolver
struct and calls its Hello
method.
We then create an HTTP handler using the github.com/graphql-go/handler
package, which handles incoming requests and serves the GraphQL API. Finally, we start a server that listens on port 8080 and handles requests using our GraphQL handler.
Handling Mutations
To demonstrate handling mutations, let’s add a new field called setMessage
to our schema. This field will allow the client to set a custom message. Update the schema.graphql
file with the following code:
type Mutation {
setMessage(message: String!): String!
}
schema {
query: Query
mutation: Mutation
}
Next, update the server.go
file with the following code:
// ...
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: // ... (existing code)
Mutation: graphql.NewObject(graphql.ObjectConfig{
Name: "Mutation",
Fields: graphql.Fields{
"setMessage": &graphql.Field{
Type: graphql.String,
Args: graphql.FieldConfigArgument{
"message": &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
message, _ := p.Args["message"].(string)
// Handle mutation logic here
return message, nil
},
},
},
}),
})
// ...
In this code, we added a new mutation field called setMessage
to the schema. We defined an argument called message
of type String!
, which is a non-null string.
We updated the resolver to handle the setMessage
mutation. The Resolve
function accesses the value of the message
argument from the ResolveParams
and returns it as the result.
Now, our GraphQL server is capable of handling both queries and mutations.
Testing the GraphQL Server
To test our GraphQL server, we can use the GraphiQL interface. Open your browser and navigate to http://localhost:8080/graphql
. You should see the GraphiQL interface, where you can execute queries and mutations.
For example, to test the hello
query, enter the following code in the GraphiQL editor and click the “Play” button:
query {
hello
}
The server should respond with the following JSON:
{
"data": {
"hello": "Hello, world!"
}
}
You can also test the setMessage
mutation by entering the following code in the GraphiQL editor:
mutation {
setMessage(message: "Hello, GraphQL!")
}
The server should respond with the following JSON:
{
"data": {
"setMessage": "Hello, GraphQL!"
}
}
Congratulations! You have successfully built a GraphQL server in Go.
Conclusion
In this tutorial, we learned how to build a GraphQL server in Go. We started by creating a schema that defines the structure and operations of our API. We then implemented resolvers to handle queries and mutations. Finally, we tested the server using the GraphiQL interface.
By understanding and implementing GraphQL servers in Go, you can create powerful and efficient APIs that provide flexible data querying capabilities to your clients.