SlideShare a Scribd company logo
GRAPHQL IN GO
MODERNWEB 2018
ABOUT ME
Open source contributor
1. Gitea
2. Drone
3. Gin
appleboy @ GitHub
appleboy @ twitter
appleboy @ slideshare
appleboy46 @ facebook
2
AGENDA
▸ Why we moving API from REST to Graphql?
▸ What is Graphql?
▸ Graphql in Golang (Why we choose Golang)
▸ How to testing Graphql in Golang
▸ Deploy Graphql application
MOVING REST TO GRAPHQL
icon from https://bit.ly/2LhOpZA
1. LARGE REQUEST IN SINGLE PAGE
https://bit.ly/2NpS4Fu
1. LARGE REQUEST IN SINGLE PAGE
CUSTOM FIELDS
/api/scene/1?field=name,description,created_at
CUSTOMENDPOINT
/api/scene/1/mobile?field=name,description
/api/scene/1/web?field=name,description
DOCUMENTATION?
HOW TO GENERATE DOCUMENT AUTOMATICALLY?
API DOC
Swagger
UPDATE API
GENERATE DOC
BACKEND
FRONTEND MOBILETESTING
/**
* @api {get} /scene/:id Request Scene information
* @apiName GetScene
* @apiGroup Scene
*
* @apiParam {Number} id Scenes unique ID.
*
* @apiSuccess {String} title Title of the Scene.
* @apiSuccess {String} desc Description of the Scene.
*/
GRAPHQL
WHATISGRAPHQL?
IT IS A QUERY LANGUAGE
{
myScene {
name
description
}
}
LEXED
PARSED
VALIDATED
EXECUTED
{
scene(id: 1) {
name
description
}
}
LEXED
PARSED
VALIDATED
EXECUTED
{
scene(id: 1) {
name
description
items(type: DEVICE) {
id
name
url
}
}
}
Graphql Request
{
"scene": {
"name": "foo",
"description": “bar",
"items": [{
"id": 1,
"name": "test_1",
"url": "http://foo.com"
}, {
"id": 2,
"name": "test_2",
"url": "http://bar.com"
}]
}
}
JSON Response
/api/scene/1
/api/scene/1/item
/api/scene/1/all
TYPE SYSTEM
GRAPHQL LANGUAGE
{
myScene {
name
description
}
}
{
scene(id: 1) {
name
description
items(type: DEVICE) {
id
name
url
}
}
}
type QueryRoot {
myScene: Scene
scene(id: ID!): Scene
}
{
scene(id: 1) {
name
description
items(type: DEVICE) {
id
name
url
}
}
}
Graphql Request
type Scene {
name: String!
description: String
items(type: ItemEnum): [Item]
}
enum ItemEnum {
DEVICE,
TEST_DEVICE,
URL
}
{
scene(id: 1) {
name
description
items(type: DEVICE) {
id
name
url
}
}
}
Graphql Request
type Item {
id: ID!
name: String!
url: String
}
INTROSPECTION
GRAPHQL LANGUAGE
{
__schema {
queryType {
name
}
}
}
{
"data": {
"__schema": {
"queryType": {
"name": "Query"
}
}
}
}
WHY NEED THE INTROSPECTION
▸code generation
▸auto documentation
▸static validation
▸IDE Integration
https://github.com/prismagraphql/graphql-playground
https://www.prisma.io/blog/introducing-graphql-playground-f1e0a018f05d/
RESOLVINGFIELDS
GRAPHQL LANGUAGE
type Item {
id: ID
type: sceneEnum
name: String
}
    "id": &graphql.Field{
      Type: graphql.Int,
    },
INT FLOAT STRING BOOLEAN ID
type Item {
id: ID
type: sceneEnum
name: String
}
    "TEST_DEVICE": &graphql.EnumValueConfig{
      Value: int(model.TypeTestDevice),
      Description: "test device.",
    },
    "DEVICE": &graphql.EnumValueConfig{
      Value: int(model.TypeDevice),
      Description: "device.",
    },
    "URL": &graphql.EnumValueConfig{
      Value: int(model.TypeURL),
      Description: "url.",
    },
"name": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
o, _ := p.Source.(*model.Scene)
return "Hello, " + o.Name, nil
},
},
Return Custom Value
MUTATION
GRAPHQL LANGUAGE
mutation {
createScene(
title: "foo",
description: "bar"
) {
id
title
description
url
}
}
// Schema is the GraphQL schema served by the server.
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
  Query: rootQuery,
  Mutation: rootMutation,
  Types: types,
})
Query and Mutation
SINGLE ENDPOINT
POST /graphql
GRAPHQL IN GOLANG
WHY WE CHOOSE GOLANG?
WHY WE CHOOSE GOLANG?
▸Compiles Into Single Binary
▸Static Type System
▸Performance
▸Easy to Deploy
▸Learning Curve
BENCHMARKOFGRAPHQLFRAMEWORKINGOLANG
▸graphql-go/graphql
▸playlyfe/go-graphql
▸graph-gophers/graphql-go
▸samsarahq/thunder
https://github.com/appleboy/golang-graphql-benchmark
$	go	test	-v	-bench=.	-benchmem
VEKTAH/GQLGEN
GO GENERATE BASED GRAPHQL SERVER
LIBRARY
https://github.com/vektah/gqlgenhttps://youtu.be/3dpqYMqyiOg
GraphQL IN Golang
API SERVER
API SERVER
GRAPHQLSERVER
GRAPHQL GATEWAY
GRAPHQLINGOLANG
PACKAGE IN GOLANG
FRAMEWORKINGO
func Handler() gin.HandlerFunc {
  h := handler.New(&handler.Config{
    Schema: &schema.Schema,
    Pretty: true,
  })
  return func(c *gin.Context) {
    h.ServeHTTP(c.Writer, c.Request)
  }
}
graphql schema
JWT TOKEN
SERVER
GRAPHQL
SERVER
func Check() gin.HandlerFunc {
  return func(c *gin.Context) {
    token := c.GetHeader("Authorization")
    user, err := authUser(token)
    if token != "" && err != nil {
      logrus.Errorf("authUser error: %s", err.Error())
    }
    if user != nil && user.Email != "" {
      c.Set("email", user.Email)
      c.Set("user_id", user.UserID)
    }
    ctx := context.WithValue(
      c.Request.Context(),
      config.ContextKeyUser,
      user,
    )
    c.Request = c.Request.WithContext(ctx)
  }
}
store user data
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
  Query: rootQuery,
  Mutation: rootMutation,
})
var rootMutation = graphql.NewObject(
  graphql.ObjectConfig{
    Name: "RootMutation",
    Description: "Root Mutation",
    Fields: graphql.Fields{
      "updateUser": &updateUser,
      "createScene": &createScene,
      "updateScene": &updateScene,
      "deleteScene": &deleteScene,
    },
  })
var rootQuery = graphql.NewObject(
  graphql.ObjectConfig{
    Name: "RootQuery",
    Description: "Root Query",
    Fields: graphql.Fields{
      "queryUser": &queryUser,
      "searchUser": &searchUser,
      "queryScene": &queryScene,
    },
  })
query
mutation
GRAPHQL ERROR
BETTER ERROR HANDLING
{	
		"data":	{	
				"post":	null	
		},	
		"errors":	[	
				{	
						"message":	"Internal	Error:	404	not	found",	
						"locations":	[	
								{	
										"line":	2,	
										"column":	3	
								}	
						],	
						"path":	[	
								"post"	
						]	
				}	
		]	
}	
single message
error location
func (g FormattedError) MarshalJSON() ([]byte, error)
{
  m := map[string]interface{}{}
  for k, v := range g.Extensions {
    m[k] = v
  }
  m["message"] = g.Message
  m["locations"] = g.Locations
  return json.Marshal(m)
}
Marshal JSON
custom key value
func FormatError(err error, arg ...interface{}) gqlerrors.FormattedError
{
  switch err := err.(type) {
  case gqlerrors.FormattedError:
    return err
  case *Error:
    return gqlerrors.FormattedError{
      Message: fmt.Sprintf(err.Error(), arg...),
      Extensions: gqlerrors.ErrorExtensions{
        "code": err.Type.Code(),
        "type": err.Type,
      },
    }
} custom error
original error
GRAPHQL N+1
DATA LOADER
1. LARGE REQUEST IN SINGLE PAGE
{
myScene(id: 1) {
name
description
role {
id
user {
email
}
model
}
}
}
ORM IN GOLANG
GOORM VS XORM
type Scene struct {
  ID int64 `xorm:"pk autoincr" json:"id"`
  Image string `json:"image,omitempty"`
  CreatedAt time.Time `json:"createdAt,omitempty"`
  UpdatedAt time.Time `json:"updatedAt,omitempty"`
  DeletedAt time.Time `xorm:"deleted"`
  // reference
  Items []*SceneItem `xorm:"-" json:"items,omitempty"`
  User *User `xorm:"-" json:"user,omitempty"`
  Role *SceneAccess `xorm:"-" json:"role,omitempty"`
}
Data Model
user role permission
 "user": &graphql.Field{
   Type: userType,
   Resolve: func(p graphql.ResolveParams) (interface{}, error) {
     o, ok := p.Source.(*model.Shorten)
     if !ok {
       return nil, errMissingSource
     }
     if o.User != nil {
       return o.User, nil
     }
     return getUserFromLoader(p.Context, o.UserID)
   },
 },
exist in model?
fetch from loader
GET DATA FROM DATABASE IF NOT EXIST
func userBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
  var results []*dataloader.Result
  id, _ := helper.GetCacheID(keys[0].String())
  user, err := model.GetUserByID(id.(int64))
  results = append(results, &dataloader.Result{
    Data: user,
    Error: err,
  })
  return results
}
fetch from DB
GRAPHQLDATALOADER
ONLY SUPPORT MEMORY, LRU OR TTL
CACHE
INTEGRATE WITH REDIS SERVICE
GRAPHQLDATALOADER
func	batchFunc(_	context.Context,	keys	dataloader.Keys)	[]*dataloader.Result	
{	
		results	:=	make([]*dataloader.Result,	len(keys))		
		//	get	what	you	can	from	redis	
		values,	_	:=	redisClient.MGet(...keys.Keys()).Result()	
		//	make	a	list	of	everything	that	was	not	found	in	redis	
		var	cacheMisses	map[int]string	
		for	i	:=	range	keys	{	
				if	values[i]	==	redis.Nil	{	
						cacheMisses[i]	=	keys[i].String()	
				}	else	{	
						results[i]	=	&dataloader.Result{values[i],	nil}	
				}	
		}	
		//	get	the	missing	items	from	more	expensive	location	(like	DB)	
		for	idx,	key	:=	range	cacheMisses	{	
				value,	err	:=	db.GetValues(key)	//	Pseudo	code!	
				redisClient.Set(key,	value)	
				results[idx]	=	&dataloader.Result{value,	err}	
		}	
		return	results	
}	
miss from redis
fetch from DB
HOW TO TEST GRAPHQL SCHEMA?
GRAPHQL TESTING
https://code.likeagirl.io/the-7-steps-to-a-complete-code-review-abdfd39e75f1
RAILS-LIKE TEST FIXTURES FOR GO
GO TEST FIXTURES
https://github.com/go-testfixtures/testfixtures
-
id: 1
email: foo@gmail.com
full_name: foo
avatar: http://foo.com
avatar_email: foo@gmail.com
-
id: 2
email: bar@gmail.com
full_name: bar
avatar: http://bar.com
avatar_email: bar@gmail.com
real data in DB
    test := T{
      Query: `
query QueryShortenURL (
$slug: String!
) {
QueryShortenURL(slug: $slug) {
url
}
}
   `,
      Schema: Schema,
      Expected: &graphql.Result{
        Data: map[string]interface{}{
          "QueryShortenURL": map[string]interface{}{
            "url": "http://example.com",
          },
        },
      },
    }
graphql query
expect data
  params := graphql.Params{
    Schema: test.Schema,
    RequestString: test.Query,
    Context: ctx,
    VariableValues: map[string]interface{}{
      "slug": "abcdef",
    },
  }
  testGraphql(test, params, t)
ctx := newContextWithUser(context.TODO(), user)
user data in context
graphql variable
all pass
testing in sqlite
GRAPHQLDEPLOYMENT
HOW TO DEPLOY GOLANG APP?
GO-GGZ/GGZ
AN URL SHORTENER SERVICE WRITTEN IN GO
https://github.com/go-ggz/ggz
Thanks

More Related Content

PPT
Graphql presentation
PDF
React & GraphQL
PPTX
An intro to GraphQL
PDF
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
PPTX
Introduction to GraphQL
PPTX
PPTX
Introduction to graphQL
PDF
REST vs GraphQL
Graphql presentation
React & GraphQL
An intro to GraphQL
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
Introduction to GraphQL
Introduction to graphQL
REST vs GraphQL

What's hot (20)

PDF
How to GraphQL
PPTX
Introduction to GraphQL
PDF
Introduction to GraphQL (or How I Learned to Stop Worrying about REST APIs)
PDF
Introduction to elasticsearch
ODP
Google's Dremel
PPTX
Intro GraphQL
PPTX
REST Easy with Django-Rest-Framework
PPTX
Elastic search overview
PDF
Intro to GraphQL
PDF
Introduction to GraphQL
PDF
PDF
Explore your prometheus data in grafana - Promcon 2018
PDF
Nodejs - A performance que eu sempre quis ter
PPTX
MySQL Monitoring using Prometheus & Grafana
PDF
Introduction to Apache Hive
PDF
What Is ELK Stack | ELK Tutorial For Beginners | Elasticsearch Kibana | ELK S...
PPTX
Express js
PDF
Elasticsearch Tutorial | Getting Started with Elasticsearch | ELK Stack Train...
PPTX
React js programming concept
PPTX
GraphQL Introduction
How to GraphQL
Introduction to GraphQL
Introduction to GraphQL (or How I Learned to Stop Worrying about REST APIs)
Introduction to elasticsearch
Google's Dremel
Intro GraphQL
REST Easy with Django-Rest-Framework
Elastic search overview
Intro to GraphQL
Introduction to GraphQL
Explore your prometheus data in grafana - Promcon 2018
Nodejs - A performance que eu sempre quis ter
MySQL Monitoring using Prometheus & Grafana
Introduction to Apache Hive
What Is ELK Stack | ELK Tutorial For Beginners | Elasticsearch Kibana | ELK S...
Express js
Elasticsearch Tutorial | Getting Started with Elasticsearch | ELK Stack Train...
React js programming concept
GraphQL Introduction
Ad

Similar to GraphQL IN Golang (20)

PDF
REST to GraphQL migration: Pros, cons and gotchas
PDF
Let's start GraphQL: structure, behavior, and architecture
PDF
GraphQL with .NET Core Microservices.pdf
PDF
Modern APIs with GraphQL
PDF
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
PDF
Exploring GraphQL
PPTX
GraphQL API Gateway and microservices
PDF
Overview of GraphQL & Clients
PPTX
Testing Graph QL Presentation (Test Automation)
PPTX
Introduction to Testing GraphQL Presentation
PPTX
GraphQL Introduction with Spring Boot
PDF
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
PDF
GraphQL ♥︎ GraphDB
PDF
Marco Liberati - Graph analytics
PDF
GraphQL Overview and Practice
PDF
Graphql usage
PPTX
GraphQL & DGraph with Go
PDF
GraphQL for Native Apps
PDF
Intro to GraphQL on Android with Apollo DroidconNYC 2017
PDF
GraphQL IndyJS April 2016
REST to GraphQL migration: Pros, cons and gotchas
Let's start GraphQL: structure, behavior, and architecture
GraphQL with .NET Core Microservices.pdf
Modern APIs with GraphQL
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Exploring GraphQL
GraphQL API Gateway and microservices
Overview of GraphQL & Clients
Testing Graph QL Presentation (Test Automation)
Introduction to Testing GraphQL Presentation
GraphQL Introduction with Spring Boot
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
GraphQL ♥︎ GraphDB
Marco Liberati - Graph analytics
GraphQL Overview and Practice
Graphql usage
GraphQL & DGraph with Go
GraphQL for Native Apps
Intro to GraphQL on Android with Apollo DroidconNYC 2017
GraphQL IndyJS April 2016
Ad

More from Bo-Yi Wu (20)

PDF
Drone CI/CD 自動化測試及部署
PDF
用 Go 語言打造多台機器 Scale 架構
PDF
Job Queue in Golang
PDF
Golang Project Layout and Practice
PDF
Introduction to GitHub Actions
PDF
Drone 1.0 Feature
PDF
Drone CI/CD Platform
PPTX
Go 語言基礎簡介
PPTX
drone continuous Integration
PPTX
Gorush: A push notification server written in Go
PPTX
用 Drone 打造 輕量級容器持續交付平台
PPTX
用 Go 語言 打造微服務架構
PPTX
Introduction to Gitea with Drone
PDF
運用 Docker 整合 Laravel 提升團隊開發效率
PDF
用 Go 語言實戰 Push Notification 服務
PPTX
用 Go 語言打造 DevOps Bot
PPTX
A painless self-hosted Git service: Gitea
PPTX
Write microservice in golang
PPTX
用 Docker 改善團隊合作模式
PPTX
Git flow 與團隊合作
Drone CI/CD 自動化測試及部署
用 Go 語言打造多台機器 Scale 架構
Job Queue in Golang
Golang Project Layout and Practice
Introduction to GitHub Actions
Drone 1.0 Feature
Drone CI/CD Platform
Go 語言基礎簡介
drone continuous Integration
Gorush: A push notification server written in Go
用 Drone 打造 輕量級容器持續交付平台
用 Go 語言 打造微服務架構
Introduction to Gitea with Drone
運用 Docker 整合 Laravel 提升團隊開發效率
用 Go 語言實戰 Push Notification 服務
用 Go 語言打造 DevOps Bot
A painless self-hosted Git service: Gitea
Write microservice in golang
用 Docker 改善團隊合作模式
Git flow 與團隊合作

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPT
Teaching material agriculture food technology
PPTX
Big Data Technologies - Introduction.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Encapsulation theory and applications.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Modernizing your data center with Dell and AMD
PDF
KodekX | Application Modernization Development
The Rise and Fall of 3GPP – Time for a Sabbatical?
Reach Out and Touch Someone: Haptics and Empathic Computing
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
MYSQL Presentation for SQL database connectivity
20250228 LYD VKU AI Blended-Learning.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
Unlocking AI with Model Context Protocol (MCP)
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Teaching material agriculture food technology
Big Data Technologies - Introduction.pptx
Machine learning based COVID-19 study performance prediction
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Encapsulation theory and applications.pdf
Network Security Unit 5.pdf for BCA BBA.
Chapter 3 Spatial Domain Image Processing.pdf
Modernizing your data center with Dell and AMD
KodekX | Application Modernization Development

GraphQL IN Golang