之前用python+django+graphene写过项目,最近想用go来实现graphql,于是在github找到了相关的项目,按照示例,简单写了写:
package main
import (
"log"
"net/http"
//主要是依赖于这两个包
"github.com/graphql-go/graphql"
"github.com/graphql-go/handler"
)
github.com/graphql-go/graphql这个包主要是实现graphql的schema和resolve的定义,而github.com/graphql-go/handler中间件则用于处理graphql的http请求。
//定义返回参数
var studentsType = graphql.NewObject(
graphql.ObjectConfig{
Name: "students",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.Int,
},
"name": &graphql.Field{
Type: graphql.String,
},
},
},
)
以上代码,定义了返回学生的id是int类型,name是string类型。
// 定义请求体
fields := graphql.Fields{
"students": &graphql.Field{
// 将返回参数类型加入请求体
Type: studentsType,
// Type: graphql.NewList(studentsType),
// 定义请求参数
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"name": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
// 定义接口函数 业务逻辑在接口函数中实现
Resolve: resolve_students,
},
}
input参数使用的是graphql.FieldConfigArgument map类型定义, 请求体中,返回数据可以是json{}类型,也可以是数组嵌套json[{}]类型,这时需要调用graphql.NewList函数。
//业务逻辑函数
resolve_students := func (p graphql.ResolveParams) (interface{}, error) {
// 类型断言
id, _ := p.Args["id"].(int)
name, _ := p.Args["name"].(string)
ret := []map[string] interface{}{}
ret = append(ret, map[string]interface{}{
"id": 1,
"name": "zhangsan",
}, map[string]interface{}{
"id": 2,
"name": "lisi",
})
for _, item := range(ret){
if item["id"] == id && item["name"] == name {
return item, nil
}
}
return nil, nil
}
主要是处理业务逻辑,此时任意发挥,但需注意返回的数据类型要与之前定义的相匹配。
rootQuery := graphql.ObjectConfig{Name: "Query", Fields: fields}
schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
schema, err := graphql.NewSchema(schemaConfig)
if err != nil {
log.Fatalf("failed to create new schema, error: %v", err)
}
// 用graphql-go/handler中间件处理graphql的http请求
h := handler.New(&handler.Config{
Schema: &schema,
Pretty: true,
GraphiQL: true,
})
// 定义路由端口
http.Handle("/graphql", h)
http.ListenAndServe(":9090", nil)
总体感觉相比与python+django+graphene,go的实现要复杂些,但大体逻辑都是差不多的,有兴趣的小伙伴都可以了解对比下。