GraphQL Delivery on Golang’s Clean Architecture

Implement GraphQL on Golang Clean Architecture

Ridho perdana
Sep 24 · 5 min read
Photo by RoseBox رز باکس on Unsplash

Clean architecture, is one of the popular architecture in programming. It’s known for its good separation concern between each layer. Each layer doesn’t need to know about the other layer implementation, so we can easily change the implementation without making changes on the other layer. If you want to know more about clean architecture, you can read it here because I won’t tell detailed explanation about it in this post.

Today, I want to try implementing GraphQL in my friend code about clean architecture in Golang, you can read his awesome post here “Trying Clean Architecture on Golang”. On that post, the writer uses REST API as the delivery layer, now I will try to add more HTTP layer which is using GraphQL.


GraphQL

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

In other’s word, GraphQL is a query language for Client to get only what they ask, without receiving unused data. So if we have an article object like this one:

{
"id": "article-id",
"title": "Indonesia won the award of best clean air of South East Asia",
"author": "Kurio"
}

And the Client only wants the title field, the server will only return:

{
"title": "Indonesia won the award of best clean air of South East Asia"
}

GraphQL Schema

article struct

We can make Article type on our GraphQL Schema like this one:

Type on the GraphQL schema

On GraphQL, it has 5 default scalar type, there are:

  • Int
  • Float
  • String
  • Boolean
  • ID

With that, we can map our Golang string and int64 datatype to String and Int scalar types on GraphQL. For the Time type on Golang, GraphQL support creating a custom scalar types, so we need to define Time scalar types in the schema we wrote.

After creating the object type, we need to create Query and Mutation for the GraphQL schema. These 2 types will be created based on Usecase interface of the clean architecture code here is the code of the usecase interface:

usecase interface code

What is the difference between Query and Mutation in GraphQL? For short Query is used to retrieve data, and Mutation is used to modify or create data on the server. So based on the usecaseinterface, we can write Query and Mutation like this one:

query and mutation schema

You must be asking,

Wait, what is ArticlesResult on FetchArticle line? There is no ArticlesResult type in the type schema before! Why not just returning list of articles instead?

In FetchArticle function, we need pagination and cursoring feature so we will not get all the articles by one request. In GraphQL, there is a standard type for implementing pagination, based on this page we need to create a connection (edge) and the info (pageInfo) of the current object, and that’s why we need to create ArticlesResult object. Here’s the schema type for the ArticlesResult:

articles_result GraphQL schema

Edge type will have cursor with String type and node with Article type. cursor is the connection value for the current article with its neighborhood article. We can get the next article with this cursor value.

PageInfo type will have endCursor with String type and hasNextPage with Boolean type. endCursor is the value of the last cursor of the current edges, so we can get the next edges with this value. hasNextPage will be our flag whether this list of edge has next page or not.

ArticlesResult type will have edges type with an array of Edge type, pageInfo with PageInfo type, and totalCount with Int type. totalCount will have the value of total items of the current edges.

All of the GraphQL type (object, mutation, and schema) can be written in the same file, so here is the schema.graphql file:

schema.graphql

Dive into GraphQL Go

Transforming object type schema

schema go object based on GraphQL schema

Preparing Resolver

resolver.go

Creating Schema Constructor

schema_object constructor

Implementing Resolver

Why don’t we just directly inject the article repository layer? It is because we treat resolver as another delivery layer, the delivery layer cannot directly access the repository layer, so we need to utilize the service layer.

  • FetchArticle
FetchArticle implementation
  • UpdateArticle
UpdateArticle implementation

I think it will be a good practice to write the other implementation by yourself, so you can explore what other options the package has. But overall, the code will be written like this:

resolver.go with implementation

Initializing the GraphQL Delivery

We use https://github.com/graphql-go/handler package to create a GraphQL HTTP handler and pass the handler into echo WrapHandler function, but if you don’t want to use it, you can create your own Handler by following the rules from https://graphql.org/learn/serving-over-http/.

Now our go-clean-arch already have another delivery layer which uses GraphQL, just run your application and access it from /graphql path. We will also have GraphiQL user interface to try the query of GraphQL.

graphiql user interface

Hope this tutorial helps you to understand about GraphQL and the usefulness of Clean Architecture in Golang.

You can see the full code from my Github here:

Have a great day 🖖🏼!


Thanks to Iman Tumorang for the Clean Code Architecture in Golang, Bastian Paskal Situmorang, Reza Indra, Nugroho Cahyono from Kurio which help me implement GraphQL in Golang 😎

Easyread

Easy read, easy understanding. A good writing is a writing that can be understood in easy ways

Thanks to Iman Tumorang

Ridho perdana

Written by

Easyread

Easyread

Easy read, easy understanding. A good writing is a writing that can be understood in easy ways

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade