Build a Simple GraphQL API in Go: Step‑by‑Step Tutorial
This tutorial shows how to wrap the jsonplaceholder REST service with a GraphQL layer in Go, covering data models, schema creation, resolver functions, server setup, and example queries with results.
Introduction
GraphQL is appearing in more and more projects. This article demonstrates how to wrap an existing REST API (jsonplaceholder) with a GraphQL layer using Go, focusing on practical implementation rather than theory.
Implementation
First, define the data models for posts and comments.
type Post struct {
UserID int `json:"userId"`
ID int `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
}
type Comment struct {
PostID int `json:"postId"`
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Body string `json:"body"`
}Helper functions fetchPostByID and fetchCommentsByPostID retrieve data from the REST endpoints and unmarshal the JSON into the structs.
Next, create the GraphQL query type, which exposes a single field post that accepts an id argument.
func createQueryType(postType *graphql.Object) graphql.ObjectConfig {
return graphql.ObjectConfig{Name: "QueryType", Fields: graphql.Fields{
"post": &graphql.Field{
Type: postType,
Args: graphql.FieldConfigArgument{"id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.Int)}},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
id := p.Args["id"]
v, _ := id.(int)
log.Printf("fetching post with id: %d", v)
return fetchPostByID(v)
},
},
}}
}Define the Post GraphQL object, mapping struct fields and adding a comments field whose resolver fetches related comments.
func createPostType(commentType *graphql.Object) *graphql.Object {
return graphql.NewObject(graphql.ObjectConfig{
Name: "Post",
Fields: graphql.Fields{
"userId": &graphql.Field{Type: graphql.NewNonNull(graphql.Int)},
"id": &graphql.Field{Type: graphql.NewNonNull(graphql.Int)},
"title": &graphql.Field{Type: graphql.String},
"body": &graphql.Field{Type: graphql.String},
"comments": &graphql.Field{
Type: graphql.NewList(commentType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
post, _ := p.Source.(*Post)
log.Printf("fetching comments of post with id: %d", post.ID)
return fetchCommentsByPostID(post.ID)
},
},
},
})
}Define the Comment GraphQL object, directly mapping the comment struct fields.
func createCommentType() *graphql.Object {
return graphql.NewObject(graphql.ObjectConfig{
Name: "Comment",
Fields: graphql.Fields{
"postId": &graphql.Field{Type: graphql.NewNonNull(graphql.Int)},
"id": &graphql.Field{Type: graphql.NewNonNull(graphql.Int)},
"name": &graphql.Field{Type: graphql.String},
"email": &graphql.Field{Type: graphql.String},
"body": &graphql.Field{Type: graphql.String},
},
})
}Assemble the schema and start an HTTP server with the graphql-go-handler middleware.
func main() {
schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: graphql.NewObject(createQueryType(createPostType(createCommentType())) )})
if err != nil {
log.Fatalf("failed to create schema, error: %v", err)
}
handler := gqlhandler.New(&gqlhandler.Config{Schema: &schema})
http.Handle("/graphql", handler)
log.Println("Server started at http://localhost:3000/graphql")
log.Fatal(http.ListenAndServe(":3000", nil))
}After the server is running, you can query a post by ID and optionally request its comments using GraphiQL.
query {
post(id: 5) {
userId
id
title
body
comments {
id
email
name
}
}
}The response includes the post fields and, when requested, an array of comment objects.
{
"data": {
"post": {
"userId": 1,
"id": 5,
"title": "...",
"body": "...",
"comments": [
{"id": 21, "email": "...", "name": "..."},
...
]
}
}
}Conclusion
This example shows how a simple Go layer can turn an existing REST API into a GraphQL service using the graphql-go library. The approach prioritises clarity, and readers are encouraged to adapt it to their own projects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
360 Zhihui Cloud Developer
360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
