热点新闻
532.【博客开发】服务端接口实现(二)
2023-07-06 06:32  浏览:296  搜索引擎搜索“手机展会网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在手机展会网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

上一篇咱们实现了几乎所有的数据库访问代码。这一次咱们进一步实现 GraphQL 接口封装。

一、GraphqQL 模式建立

  1. 基础模式:

var baseType = graphql.NewObject(graphql.ObjectConfig{ Name: "base", Fields: graphql.Fields{ "id": &graphql.Field{Type: graphql.ID}, "created_at": &graphql.Field{Type: graphql.DateTime}, "updated_at": &graphql.Field{Type: graphql.DateTime}, "deleted_at": &graphql.Field{Type: graphql.DateTime}, }, Description: "baseType", })

  1. 基础维度模式:

var baseDimensionType = graphql.NewObject(graphql.ObjectConfig{ Name: "baseDimension", Fields: graphql.Fields{ "name": &graphql.Field{Type: graphql.String}, "category": &graphql.Field{Type: graphql.String}, "content": &graphql.Field{Type: graphql.String}, "tag": &graphql.Field{Type: graphql.String}, }, Description: "baseDimensionType", })

  1. 账号模式:

var userType = graphql.NewObject(graphql.ObjectConfig{ Name: "User", Fields: graphql.Fields{ "account": &graphql.Field{Type: graphql.String}, "password": &graphql.Field{Type: graphql.String}, "time_account_change_latest": &graphql.Field{Type: graphql.DateTime}, "time_login_one": &graphql.Field{Type: graphql.DateTime}, "time_login_second": &graphql.Field{Type: graphql.DateTime}, "base": &graphql.Field{Type: baseType}, "dimension_readings": &graphql.Field{Type: graphql.NewList(dimensionReadingType)}, "dimension_writings": &graphql.Field{Type: graphql.NewList(dimensionWritingType)}, "dimension_photos": &graphql.Field{Type: graphql.NewList(dimensionPhotoType)}, "eco_comments": &graphql.Field{Type: graphql.NewList(ecoCommentType)}, "system_ads": &graphql.Field{Type: graphql.NewList(systemAdType)}, "bind_profiles": &graphql.Field{Type: graphql.NewList(bindProfileType)}, }, Description: "userType", })

  1. 维度模式(例如:阅读金句):

var dimensionReadingType = graphql.NewObject(graphql.ObjectConfig{ Name: "DimensionReading", Fields: graphql.Fields{ "author": &graphql.Field{Type: graphql.String}, "location": &graphql.Field{Type: graphql.String}, "base_dimension": &graphql.Field{Type: baseDimensionType}, "eco_comments": &graphql.Field{Type: graphql.NewList(ecoCommentType)}, "users": &graphql.Field{Type: graphql.NewList(userType)}, }, Description: "dimensionReadingType", })

  1. 生态模式(例如:评论):

var ecoCommentType = graphql.NewObject(graphql.ObjectConfig{ Name: "EcoComment", Fields: graphql.Fields{ "data": &graphql.Field{Type: graphql.String}, "is_published": &graphql.Field{Type: graphql.Boolean}, "base": &graphql.Field{Type: baseType}, }, Description: "ecoCommentType", })

二、GraphQL 端点(Endpoint)建立

  1. Endpoint构建,以维度为例(其他的都类似):

var EndpointGetDimensionReading = &graphql.Field{ Type: responseDimensionReadingType, Args: graphql.FieldConfigArgument{ "from_id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)}, "from_nickname": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)}, "content": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.String), Description: "query by cond", }, }, Resolve: func(p graphql.ResolveParams) (i interface{}, err error) { var entities []DimensionReading var count int64 content, contentOk := p.Args["content"].(string) fromId, fromIdOk := p.Args["from_id"].(string) fromNickname, fromNicknameOK := p.Args["from_nickname"].(string) if !contentOk || !fromIdOk || !fromNicknameOK || fromId == "" || fromNickname == "" || content == "" { return nil, errors.New("required id,name,content") } var condGetDetails CondGetDetails if !contentOk { return nil, errors.New("参数解析失败") } err = json.Unmarshal([]byte(content), &condGetDetails) if err != nil { return nil, errors.New("参数解析失败") } result, err := GetEntities(condGetDetails) if err != nil { return nil, err } err = result.Preload(clause.Associations).Find(&entities).Count(&count).Error return ResponseCommon{ Code: 200, Content: entities, Count: count, Msg: Message{ Success: "success", }, }, err }, }

  • 每个接口访问时,除了接口必要的参数数据之外,还附带上额外的用户数据(idnickname),方便以后的审计
  • content 是接口必要的参数数据,使用的是前面的文章中设计好的数据结构
  • 博客系统的所有接口参数尽量保持一致——这是一个能简化逻辑的约定。
  1. GraphQL 的 endpoint 接入到 Gin 框架内:

var queryType = graphql.NewObject(graphql.ObjectConfig{ Name: "Query", Fields: graphql.Fields{ "dimensionReading": EndpointGetDimensionReading, //获取参展项目列表 }, }) var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{ Query: queryType, //Mutation: mutationType, }) func ExecuteQuery(schema graphql.Schema, query string, variables map[string]interface{}, operationName string) *graphql.Result { result := graphql.Do(graphql.Params{ Schema: schema, RequestString: query, Variablevalues: variables, OperationName: operationName, }) if len(result.Errors) > 0 { log.Printf("errors:%s", result.Errors) } return result }

  • Gin 框架与 GraphQL 的中间连接代码

func RouterDimension(router *gin.Engine) (interface{}, error) { routerDimension := router.Group("/blog/x") { routerDimension.POST("/v1", func(c *gin.Context) { var query Query err := c.BindJSON(&query) if err != nil { log.Println(err) c.JSON(http.StatusOK, err) return } result := models.ExecuteQuery(models.Schema, query.Query, query.Variables, query.OperationName) // 此处连接GraphQL c.JSON(http.StatusOK, result) }) } return routerDimension, nil }

  • Gin 路由相关代码实现。
发布人:d1d1****    IP:125.64.05.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发