Build a Hacker News GraphQL API with Go: Step‑by‑Step Guide
Learn how to replace RESTful endpoints with a GraphQL service by creating a Hacker News API in Go, covering core concepts, type and field definitions, query and mutation setup, and essential resolver implementations illustrated with complete code examples.
GraphQL provides an efficient, clear specification that can replace the popular RESTful architecture, offering a flexible query language, static typing, and standards that improve front‑end and back‑end collaboration. The author, a front‑end developer, shares a desire to replace undocumented interfaces with GraphQL to boost development efficiency.
Before writing code, you can try an existing GraphQL demo that mimics the Hacker News official API, exposing article and user information.
Core concepts of a GraphQL service
Type : The basic building block; a GraphQL service returns data defined by a type, similar to a class in object‑oriented programming.
Field : Fields compose a type; each field has its own return type, analogous to a class property.
Query : Queries expose all read operations; a query is a type made up of fields.
Mutation : Mutations expose write operations; a mutation is also a type composed of fields.
Types and fields depend on each other
Since a type consists of fields, the core work of building a GraphQL service is writing fields; data fetching and write‑logic are implemented inside field resolvers.
All query entry points (query)
var RootQuery = graphql.NewObject(graphql.ObjectConfig{
Name: "RootQuery",
Description: `hackernews's API`,
Fields: graphql.Fields{
"story": &graphql.Field{
Type: storyType,
Description: `get story item by story.id`,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.Int),
Description: "item's unique id",
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
if id, ok := p.Args["id"].(int); ok {
return model.GetStory(int32(id))
}
return nil, nil
},
},
"topstories": &graphql.Field{
Type: graphql.NewList(storyType),
Description: `Up to 500 top stories`,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
ids := []int32{}
model.GetKV("topstories", &ids)
return model.GetStories(ids), nil
},
},
},
})The above code defines two query fields: story – fetches a story by its ID, returning storyType. topstories – retrieves up to 500 popular stories, returning [storyType].
Data retrieval logic resides in the Resolve functions; the underlying model code that accesses the database is omitted for brevity.
storyType definition
var storyType = graphql.NewObject(graphql.ObjectConfig{
Name: "Story",
Description: `Stories, They're identified by their ids, which are unique integers.
All items have some of the following properties.
`,
Fields: graphql.Fields{
"id": idField,
"by": byField,
"time": timeField,
"deleted": deletedField,
"dead": deadField,
"text": textField,
"score": scoreField,
"url": urlField,
"title": titleField,
"descendants": descendantsField,
"doc": docField,
"comments": &graphql.Field{
Name: "comments",
Description: `this poll's comments`,
Type: graphql.NewList(commentType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
poll := p.Source.(*model.Poll)
return model.GetComments(poll.Kids), nil
},
},
},
})This code specifies the structure of storyType and how each field obtains its data. For example, the comments field uses a resolver to fetch all comments associated with a story.
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.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
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.
