go + graphql的简单实现

之前用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的实现要复杂些,但大体逻辑都是差不多的,有兴趣的小伙伴都可以了解对比下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容