Golang Gin GraphQL 搭建 api 框架

Golang

Go 是 Google 開發的一種靜態強類型、編譯型、併發型,並具有垃圾回收功能的編程語言。爲了方便搜索和識別,有時會將其稱爲 Golang。

GraphQL

GraphQL 既是一種用於 API 的查詢語言也是一個滿足你數據查詢的運行時。

Gin

Gin is a HTTP web framework written in Go (Golang).

爲什麼要用 GraphQL?

爲了讓 api 具有更強的適應性,採用 graphql 來編寫查詢接口是個不錯的選擇。現在的 api 需要適應的場景太多了,而且迭代節奏也很快,RESTful 的查詢接口在一些複雜的場景下顯得特別的繁雜,如多重嵌套的資源。

爲什麼要用 Go?

在 Go 語言出現之前,開發者們總是面臨非常艱難的抉擇,究竟是使用執行速度快但是編譯速度並不理想的語言(如:C++),還是使用編譯速度較快但執行效率不佳的語言(如:.NET、Java),或者說開發難度較低但執行速度一般的動態語言呢?顯然,Go 語言在這 3 個條件之間做到了最佳的平衡:快速編譯,高效執行,易於開發。

爲什麼要用 Gin?

因爲 Gin 夠簡潔,適合定製合適自己風格的框架。

在這裏主要記錄集成 GraphQL 的部分,對於 Gin 的目錄結構組織因人而異,就不做詳細介紹。

在 Go 裏面集成 graphql 需要用到 graphql-go 這個 package,當然可以參考 GraphQL 文檔提供的其他。

// 從schema開始
// schema/schema.go
package schema

// 引入包graphql-go
import (
	"github.com/graphql-go/graphql"
)

// 定義跟查詢節點
var rootQuery = graphql.NewObject(graphql.ObjectConfig{
	Name: "RootQuery",
	Description: "Root Query",
	Fields: graphql.Fields{
		"hello": &queryHello, // queryHello 參考schema/hello.go
	},
})

// 定義Schema用於http handler處理
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
	Query:    rootQuery,
	Mutation: nil, // 需要通過GraphQL更新數據,可以定義Mutation
})
// schema/hello.go
package schema

import (
	"golesson/model"

	"github.com/graphql-go/graphql"
)

// 定義查詢對象的字段,支持嵌套
var helloType = graphql.NewObject(graphql.ObjectConfig{
	Name: "Hello",
	Description: "Hello Model",
	Fields: graphql.Fields{
		"id": &graphql.Field{
			Type: graphql.Int,
		},
		"name": &graphql.Field{
			Type: graphql.String,
		},
	},
})

// 處理查詢請求
var queryHello = graphql.Field{
	Name: "QueryHello",
	Description: "Query Hello",
	Type: graphql.NewList(helloType),
        // Args是定義在GraphQL查詢中支持的查詢字段,
        // 可自行隨意定義,如加上limit,start這類
	Args: graphql.FieldConfigArgument{
		"id": &graphql.ArgumentConfig{
			Type: graphql.Int,
		},
		"name": &graphql.ArgumentConfig{
			Type: graphql.String,
		},
	},
        // Resolve是一個處理請求的函數,具體處理邏輯可在此進行
	Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
                // Args裏面定義的字段在p.Args裏面,對應的取出來
                // 因爲是interface{}的值,需要類型轉換,可參考類型斷言(type assertion): https://zengweigang.gitbooks.io/core-go/content/eBook/11.3.html
		id, _ := p.Args["id"].(int)
		name, _ := p.Args["name"].(string)
		
                // 調用Hello這個model裏面的Query方法查詢數據
		return (&model.Hello{}).Query(id, name)
	},
}
// 準備好了GraphQL在Go裏面需要的東西之後,來看看如何跟Gin結合
// controller/graphql/graphql.go
package graphql

import (
	"golesson/schema"

	"github.com/gin-gonic/gin"
	"github.com/graphql-go/handler"
)

func GraphqlHandler() gin.HandlerFunc{
	h := handler.New(&handler.Config{
		Schema: &schema.Schema,
		Pretty: true,
		GraphiQL: true,
	})

        // 只需要通過Gin簡單封裝即可
	return func(c *gin.Context) {
		h.ServeHTTP(c.Writer, c.Request)
	}
}
// route/router.go
package router

import (
	"golesson/controller/graphql"
	
	"github.com/gin-gonic/gin"
)

var Router *gin.Engine

func init() {
	Router = gin.Default()
}

func SetRouter() {
        // GET方法用於支持GraphQL的web界面操作
        // 如果不需要web界面,可根據自己需求用GET/POST或者其他都可以
	Router.POST("/graphql", graphql.GraphqlHandler())
	Router.GET("/graphql", graphql.GraphqlHandler())
}
// main.go
package main

import "golesson/route"

func main () {
	r := router.Router

	router.SetRouter()

	r.Run(":1234")
}

運行之後的 web 界面

Github:

CNBlackJ/golesson​github.com

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://zhuanlan.zhihu.com/p/35792985?ivk_sa=1024320u