From 0bb90303cb819ab97c33b4384d83347bcdbc8974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A7=89?= Date: Tue, 21 Nov 2023 04:10:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E8=A3=85=20graphql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/graphql.go | 369 ++++++++++++++++++++++++++++--------------------- demo/main.go | 4 +- 2 files changed, 213 insertions(+), 160 deletions(-) diff --git a/api/graphql.go b/api/graphql.go index b36773c..9c5d47f 100644 --- a/api/graphql.go +++ b/api/graphql.go @@ -54,52 +54,6 @@ func NewSchema() (graphql.Schema, error) { }, }) - // 用户列表查询 - users := &graphql.Field{ - Type: graphql.NewList(user), - Args: graphql.FieldConfigArgument{ - "id": &graphql.ArgumentConfig{Type: graphql.Int}, - "user_name": &graphql.ArgumentConfig{Type: graphql.String}, - "avatar": &graphql.ArgumentConfig{Type: graphql.String}, - "rank": &graphql.ArgumentConfig{Type: graphql.String}, - "create_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, - "update_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, - }, - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - var fields []string - requestedFields := p.Info.FieldASTs[0].SelectionSet.Selections - for _, field := range requestedFields { - fieldAST, ok := field.(*ast.Field) - if ok { - fields = append(fields, fieldAST.Name.Value) - } - } - fields_str := strings.Join(fields, ",") - var where []string - if p.Args["id"] != nil { - where = append(where, fmt.Sprintf("id=%d", p.Args["id"])) - } - if p.Args["user_name"] != nil { - where = append(where, fmt.Sprintf("user_name='%s'", p.Args["user_name"])) - } - // 筛选条件 - where_str := strings.Join(where, " AND ") - fmt.Println(where_str) - - var query strings.Builder - query.WriteString(fmt.Sprintf("SELECT %s FROM web_member WHERE %s LIMIT %s", fields_str, where_str, "10")) - fmt.Println(query.String()) - - var users []User - if err := connection.Select(&users, query.String()); err != nil { - fmt.Println("获取用户列表失败", err) - return nil, err - } - fmt.Println(users) - return users, nil - }, - } - image := graphql.NewObject(graphql.ObjectConfig{ Name: "Image", Fields: graphql.Fields{ @@ -122,140 +76,239 @@ func NewSchema() (graphql.Schema, error) { }, }) - images := &graphql.Field{ - Type: graphql.NewList(image), - Args: graphql.FieldConfigArgument{ - "id": &graphql.ArgumentConfig{ - Type: graphql.Int, + schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: graphql.NewObject(graphql.ObjectConfig{Name: "RootQuery", Fields: graphql.Fields{ + "users": &graphql.Field{ + Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "UserConnection", + Fields: graphql.Fields{ + "list": &graphql.Field{Type: graphql.NewList(user)}, + "next": &graphql.Field{Type: graphql.String}, + "total": &graphql.Field{Type: graphql.Int}, + }, + }), + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{Type: graphql.Int}, + "user_name": &graphql.ArgumentConfig{Type: graphql.String}, + "avatar": &graphql.ArgumentConfig{Type: graphql.String}, + "rank": &graphql.ArgumentConfig{Type: graphql.String}, + "create_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, + "update_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, + "first": &graphql.ArgumentConfig{Type: graphql.Int, DefaultValue: 10}, // 翻页参数 + "after": &graphql.ArgumentConfig{Type: graphql.String, DefaultValue: "0"}, // 翻页参数 }, - "width": &graphql.ArgumentConfig{ - Type: graphql.Int, - }, - "height": &graphql.ArgumentConfig{ - Type: graphql.Int, - }, - "content": &graphql.ArgumentConfig{ - Type: graphql.String, - }, - }, - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - // 返回字段 - var fields []string - requestedFields := p.Info.FieldASTs[0].SelectionSet.Selections - for _, field := range requestedFields { - fieldAST, ok := field.(*ast.Field) - if ok { - if fieldAST.Name.Value == "user" { - fields = append(fields, "user_id") - } else if fieldAST.Name.Value == "article" { - fields = append(fields, "article_id") - } else { - fields = append(fields, fieldAST.Name.Value) + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + var fields []string + requestedFields := p.Info.FieldASTs[0].SelectionSet.Selections + for _, field := range requestedFields { + fieldAST, ok := field.(*ast.Field) + if ok { + if fieldAST.Name.Value == "list" { + for _, field := range fieldAST.SelectionSet.Selections { + fieldAST, ok := field.(*ast.Field) + if ok { + fields = append(fields, fieldAST.Name.Value) + } + } + } else if fieldAST.Name.Value == "next" { + fmt.Println("next") + } else { + fields = append(fields, fieldAST.Name.Value) + } } } - } - fields_str := strings.Join(fields, ",") - - // 筛选条件 - var where []string - if p.Args["id"] != nil { - where = append(where, fmt.Sprintf("id=%d", p.Args["id"])) - } - if p.Args["width"] != nil { - where = append(where, fmt.Sprintf("width=%d", p.Args["width"])) - } - if p.Args["height"] != nil { - where = append(where, fmt.Sprintf("height=%d", p.Args["height"])) - } - if p.Args["content"] != nil { - where = append(where, fmt.Sprintf("content='%s'", p.Args["content"])) - } - where_str := strings.Join(where, " AND ") - fmt.Println(where_str) - - // 执行查询 - var query strings.Builder - query.WriteString(fmt.Sprintf("SELECT %s FROM web_images WHERE %s LIMIT %s", fields_str, where_str, "10")) - fmt.Println(query.String()) - - var images []Image - if err := connection.Select(&images, query.String()); err != nil { - fmt.Println("获取图像列表失败", err) - return nil, err - } - - // 获取用户信息(如果图像列表不为空且请求字段中包含user) - if len(images) > 0 && strings.Contains(fields_str, "user_id") { - // 取到所有的用户ID, 去除重复 - user_ids := make(map[int]bool) - for _, image := range images { - user_ids[image.UserID] = true + first := p.Args["first"] + after := p.Args["after"] + fields_str := strings.Join(fields, ",") + var where []string + if p.Args["id"] != nil { + where = append(where, fmt.Sprintf("id=%d", p.Args["id"])) } - // map 转换为数组 - uniqueIds := make([]int, 0, len(user_ids)) - for id := range user_ids { - uniqueIds = append(uniqueIds, id) + if p.Args["user_name"] != nil { + where = append(where, fmt.Sprintf("user_name='%s'", p.Args["user_name"])) } - // 合并为以逗号分隔的字符串 - user_ids_str := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(uniqueIds)), ","), "[]") - fmt.Println(user_ids_str) - // 查询用户信息 + // 筛选条件 + where_str := strings.Join(where, " AND ") + var query strings.Builder + query.WriteString(fmt.Sprintf("SELECT %s FROM web_member WHERE %s LIMIT %d OFFSET %s", fields_str, where_str, first, after)) + // 返回翻页信息 + fmt.Println(query.String()) var users []User - if err := connection.Select(&users, fmt.Sprintf("SELECT id,user_name,avatar,rank,create_time,update_time FROM web_member WHERE id IN (%s)", user_ids_str)); err != nil { + if err := connection.Select(&users, query.String()); err != nil { fmt.Println("获取用户列表失败", err) return nil, err } - // 将用户信息与图像信息关联 - for i, image := range images { - for _, user := range users { - if image.UserID == user.ID { - images[i].User = user + //return users, nil + //var users []User + //// 获取用户列表 + //if err := connection.Select(&users, "SELECT id,user_name,avatar,rank,create_time,update_time FROM web_member"); err != nil { + // fmt.Println("获取用户列表失败", err) + // return nil, err + //} + //// 获取总数 + //var count int + //if err := connection.Get(&count, "SELECT COUNT(*) FROM web_member"); err != nil { + // fmt.Println("获取用户总数失败", err) + // return nil, err + //} + return map[string]interface{}{ + "list": users, + "next": "2333", + }, nil + }, + }, + "images": &graphql.Field{ + Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "ImageConnection", + Fields: graphql.Fields{ + "list": &graphql.Field{Type: graphql.NewList(image)}, + "next": &graphql.Field{Type: graphql.String}, + "total": &graphql.Field{Type: graphql.Int}, + }, + }), + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{Type: graphql.Int}, + "width": &graphql.ArgumentConfig{Type: graphql.Int}, + "height": &graphql.ArgumentConfig{Type: graphql.Int}, + "content": &graphql.ArgumentConfig{Type: graphql.String}, + "remark": &graphql.ArgumentConfig{Type: graphql.String}, + "description": &graphql.ArgumentConfig{Type: graphql.String}, + "tags": &graphql.ArgumentConfig{Type: graphql.String}, + "rank": &graphql.ArgumentConfig{Type: graphql.String}, + "comment_num": &graphql.ArgumentConfig{Type: graphql.Int}, + "praise_count": &graphql.ArgumentConfig{Type: graphql.Int}, + "collect_count": &graphql.ArgumentConfig{Type: graphql.Int}, + "article_id": &graphql.ArgumentConfig{Type: graphql.Int}, + "user_id": &graphql.ArgumentConfig{Type: graphql.Int}, + "create_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, + "update_time": &graphql.ArgumentConfig{Type: graphql.DateTime}, + "first": &graphql.ArgumentConfig{Type: graphql.Int, DefaultValue: 10}, // 翻页参数 + "after": &graphql.ArgumentConfig{Type: graphql.String, DefaultValue: "0"}, // 翻页参数 + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + // 返回字段 + var fields []string + requestedFields := p.Info.FieldASTs[0].SelectionSet.Selections + for _, field := range requestedFields { + fieldAST, ok := field.(*ast.Field) + if ok { + if fieldAST.Name.Value == "list" { + for _, field := range fieldAST.SelectionSet.Selections { + fieldAST, ok := field.(*ast.Field) + if ok { + if fieldAST.Name.Value == "user" { + fields = append(fields, "user_id") + } else if fieldAST.Name.Value == "article" { + fields = append(fields, "article_id") + } else { + fields = append(fields, fieldAST.Name.Value) + } + } + } + } else if fieldAST.Name.Value == "next" { + fmt.Println("next") + } else { + fields = append(fields, fieldAST.Name.Value) } } } - } + first := p.Args["first"] + after := p.Args["after"] + fields_str := strings.Join(fields, ",") - // 获取文章信息(如果图像列表不为空且请求字段中包含article) - if len(images) > 0 && strings.Contains(fields_str, "article_id") { - // 取到所有的文章ID, 去除重复 - article_ids := make(map[int]bool) - for _, image := range images { - article_ids[image.ArticleID] = true + // 筛选条件 + var where []string + if p.Args["id"] != nil { + where = append(where, fmt.Sprintf("id=%d", p.Args["id"])) } - // map 转换为数组 - uniqueIds := make([]int, 0, len(article_ids)) - for id := range article_ids { - uniqueIds = append(uniqueIds, id) + if p.Args["width"] != nil { + where = append(where, fmt.Sprintf("width=%d", p.Args["width"])) } - // 合并为以逗号分隔的字符串 - article_ids_str := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(uniqueIds)), ","), "[]") - fmt.Println(article_ids_str) - // 查询文章信息 - var articles []Article - if err := connection.Select(&articles, fmt.Sprintf("SELECT id,title,tags,create_time,update_time FROM web_article WHERE id IN (%s)", article_ids_str)); err != nil { - fmt.Println("获取文章列表失败", err) + if p.Args["height"] != nil { + where = append(where, fmt.Sprintf("height=%d", p.Args["height"])) + } + if p.Args["content"] != nil { + where = append(where, fmt.Sprintf("content='%s'", p.Args["content"])) + } + where_str := strings.Join(where, " AND ") + + // 执行查询 + var query strings.Builder + query.WriteString(fmt.Sprintf("SELECT %s FROM web_images WHERE %s LIMIT %d OFFSET %s", fields_str, where_str, first, after)) + fmt.Println(query.String()) + + var images []Image + if err := connection.Select(&images, query.String()); err != nil { + fmt.Println("获取图像列表失败", err) return nil, err } - // 将文章信息与图像信息关联 - for i, image := range images { - for _, article := range articles { - if image.ArticleID == article.ID { - images[i].Article = article + + // 获取用户信息(如果图像列表不为空且请求字段中包含user) + if len(images) > 0 && strings.Contains(fields_str, "user_id") { + // 取到所有的用户ID, 去除重复 + user_ids := make(map[int]bool) + for _, image := range images { + user_ids[image.UserID] = true + } + // map 转换为数组 + uniqueIds := make([]int, 0, len(user_ids)) + for id := range user_ids { + uniqueIds = append(uniqueIds, id) + } + // 合并为以逗号分隔的字符串 + user_ids_str := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(uniqueIds)), ","), "[]") + // 查询用户信息 + var users []User + if err := connection.Select(&users, fmt.Sprintf("SELECT id,user_name,avatar,rank,create_time,update_time FROM web_member WHERE id IN (%s)", user_ids_str)); err != nil { + fmt.Println("获取用户列表失败", err) + return nil, err + } + // 将用户信息与图像信息关联 + for i, image := range images { + for _, user := range users { + if image.UserID == user.ID { + images[i].User = user + } } } } - } - return images, nil + // 获取文章信息(如果图像列表不为空且请求字段中包含article) + if len(images) > 0 && strings.Contains(fields_str, "article_id") { + // 取到所有的文章ID, 去除重复 + article_ids := make(map[int]bool) + for _, image := range images { + article_ids[image.ArticleID] = true + } + // map 转换为数组 + uniqueIds := make([]int, 0, len(article_ids)) + for id := range article_ids { + uniqueIds = append(uniqueIds, id) + } + // 合并为以逗号分隔的字符串 + article_ids_str := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(uniqueIds)), ","), "[]") + // 查询文章信息 + var articles []Article + if err := connection.Select(&articles, fmt.Sprintf("SELECT id,title,tags,create_time,update_time FROM web_article WHERE id IN (%s)", article_ids_str)); err != nil { + fmt.Println("获取文章列表失败", err) + return nil, err + } + // 将文章信息与图像信息关联 + for i, image := range images { + for _, article := range articles { + if image.ArticleID == article.ID { + images[i].Article = article + } + } + } + } + + return map[string]interface{}{ + "list": images, + "next": "2333", + }, nil + }, }, - } - - rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: graphql.Fields{ - "users": users, - "images": images, - }} - schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)} - schema, err := graphql.NewSchema(schemaConfig) + }})}) if err != nil { return schema, err } diff --git a/demo/main.go b/demo/main.go index 6001204..3fd336b 100644 --- a/demo/main.go +++ b/demo/main.go @@ -27,9 +27,9 @@ func main() { http.Error(w, result.Errors[0].Error(), 500) return } - rJSON, _ := json.MarshalIndent(result, "", " ") + rJSON, _ := json.MarshalIndent(result.Data, "", " ") w.Write(rJSON) }) - + fmt.Println("Now server is running on port 6001") http.ListenAndServe(":6001", nil) }