• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

graphql GO学习

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

参考graphql-go-example

设计API参数列表

type User {
  id: ID
  email: String!
  post(id: ID!): Post
  posts: [Post!]!
  follower(id: ID!): User
  followers: [User!]!
  followee(id: ID!): User
  followees: [User!]!
}
type Post {
  id: ID
  user: User!
  title: String!
  body: String!
  comment(id: ID!): Comment
  comments: [Comment!]!
}

type Comment {
  id: ID
  user: User!
  post: Post!
  title: String
  body: String!
}

 [Type]!或者[Type!]或者[Type!]!(请仔细看这里!的位置),它们的含义分别为:

  • 列表本身为必填项,但其内部元素可以为空
  • 列表本身可以为空,但是其内部元素为必填
  • 列表本身和内部元素均为必填

转换为go的实现(User为例)

 

var UserType = graphql.NewObject(graphql.ObjectConfig{
   Name: "User",
   Fields: graphql.Fields{
      "id": &graphql.Field{
         Type: graphql.NewNonNull(graphql.ID),
         Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            if user, ok := p.Source.(*User); ok == true {
               return user.ID, nil
            }
            return nil, nil
         },
      },
      "email": &graphql.Field{
         Type: graphql.NewNonNull(graphql.String),
         Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            if user, ok := p.Source.(*User); ok == true {
               return user.Email, nil
            }
            return nil, nil
         },
      },
   },
})

func init() {
   UserType.AddFieldConfig("post", &graphql.Field{
      Type: PostType,
      Args: graphql.FieldConfigArgument{
         "id": &graphql.ArgumentConfig{
            Description: "Post ID",
            Type:        graphql.NewNonNull(graphql.ID),
         },
      },
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
               return nil, err
            }
            return GetPostByIDAndUser(id, user.ID)
         }
         return nil, nil
      },
   })
   UserType.AddFieldConfig("posts", &graphql.Field{
      Type: graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(PostType))),
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            return GetPostsForUser(user.ID)
         }
         return []Post{}, nil
      },
   })
   UserType.AddFieldConfig("follower", &graphql.Field{
      Type: UserType,
      Args: graphql.FieldConfigArgument{
         "id": &graphql.ArgumentConfig{
            Description: "Follower ID",
            Type:        graphql.NewNonNull(graphql.ID),
         },
      },
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
               return nil, err
            }
            return GetFollowerByIDAndUser(id, user.ID)
         }
         return nil, nil
      },
   })
   UserType.AddFieldConfig("followers", &graphql.Field{
      Type: graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(UserType))),
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            return GetFollowersForUser(user.ID)
         }
         return []User{}, nil
      },
   })
   UserType.AddFieldConfig("followee", &graphql.Field{
      Type: UserType,
      Args: graphql.FieldConfigArgument{
         "id": &graphql.ArgumentConfig{
            Description: "Followee ID",
            Type:        graphql.NewNonNull(graphql.ID),
         },
      },
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
               return nil, err
            }
            return GetFolloweeByIDAndUser(id, user.ID)
         }
         return nil, nil
      },
   })
   UserType.AddFieldConfig("followees", &graphql.Field{
      Type: graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(UserType))),
      Resolve: func(p graphql.ResolveParams) (interface{}, error) {
         if user, ok := p.Source.(*User); ok == true {
            return GetFolloweesForUser(user.ID)
         }
         return []User{}, nil
      },
   })
}

API查询 

graphql设计模式有三种查询类型

  • query(查询):当获取数据时,应当选取Query类型
  • mutation(更改):当尝试修改数据时,应当使用mutation类型
  • subscription(订阅):当希望数据更改时,可以进行消息推送,使用subscription类型

query和mutation设计如下:

type Query {
  user(id: ID!): User
}

type Mutation {
  createUser(email: String!): User
  removeUser(id: ID!): Boolean
  follow(follower: ID!, followee: ID!): Boolean
  unfollow(follower: ID!, followee: ID!): Boolean
  createPost(user: ID!, title: String!, body: String!): Post
  removePost(id: ID!): Boolean
  createComment(user: ID!, post: ID!, title: String!, body: String!): Comment
  removeComment(id: ID!): Boolean
}

 转换为go的实现

var QueryType = graphql.NewObject(graphql.ObjectConfig{
   Name: "Query",
   Fields: graphql.Fields{
      "user": &graphql.Field{
         Type: UserType,
         Args: graphql.FieldConfigArgument{
            "id": &graphql.ArgumentConfig{
               Description: "User ID",
               Type:        graphql.NewNonNull(graphql.ID),
            },
         },
         Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
               return nil, err
            }
            return GetUserByID(id)
         },
      },
   },
})
var MutationType = graphql.NewObject(graphql.ObjectConfig{
   Name: "Mutation",
   Fields: graphql.Fields{
      "createUser": &graphql.Field{
         Type: UserType,
         Args: graphql.FieldConfigArgument{
            "email": &graphql.ArgumentConfig{
               Description: "New User Email",
               Type:        graphql.NewNonNull(graphql.String),
            },
         },
         Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            email := p.Args["email"].(string)
            user := &User{
               Email: email,
            }
            err := InsertUser(user)
            return user, err
         },
      },
      "removeUser": &graphql.Field{
         Type: graphql.Boolean,
         Args: graphql.FieldConfigArgument{
            "id": &graphql.ArgumentConfig{
               Description: "User ID to remove",
               Type:        graphql.NewNonNull(graphql.ID),
            },
         },
         Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
               return nil, err
            }
            err = RemoveUserByID(id)
            return (err == nil), err
         },
      },    
    },
})

 接口的启用也很简单

func main() {
   schema, err := graphql.NewSchema(graphql.SchemaConfig{
      Query:    QueryType,
      Mutation: MutationType,
   })
   if err != nil {
      log.Fatal(err)
   }

   http.Handle("/graphql", handler(schema))
   log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
}
func handler(schema graphql.Schema) http.HandlerFunc {
   return func(w http.ResponseWriter, r *http.Request) {
      query, err := ioutil.ReadAll(r.Body)
      if err != nil {
         http.Error(w, err.Error(), http.StatusBadRequest)
         return
      }
      result := graphql.Do(graphql.Params{
         Schema:        schema,
         RequestString: string(query),
      })
      w.Header().Set("Content-Type", "application/json")
      w.WriteHeader(http.StatusOK)
      json.NewEncoder(w).Encode(result)
   }
}

请求实例


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang下通过syscall调用win32的dll(callingWindowsDLLsfromGo)发布时间:2022-07-10
下一篇:
go 协程发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap