范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Go使用GraphQL基础教程

  欢迎golang同胞!在本教程中,我们将研究如何在基于 Go 的程序中与 GraphQL 服务器进行交互。在本教程结束时,我们应该知道如何执行以下操作:GraphQL 的基础知识在 Go 中构建一个简单的 GraphQL 服务器针对 GraphQL 执行基本查询
  在本教程中,我们将专注于学习 GraphQL 的数据检索方面,并且我们将使用内存中的数据源来支持它。这应该为我们在后续教程的基础上建立一个良好的基础。GraphQL 基础知识
  好的,所以在我们深入研究之前,我们应该真正了解 GraphQL 的基础知识。作为开发人员,使用它对我们有什么好处?
  好吧,考虑使用每天处理数十万甚至数百万请求的系统。传统上,我们会使用位于数据库前面的系统 API,它会返回大量 JSON 响应,其中包含许多我们可能不一定需要的冗余信息。
  如果我们正在处理大规模的应用程序,发送冗余数据的成本可能会很高,并且由于有效负载大小会阻塞我们的网络带宽。
  GraphQL基本上可以让我们以减少噪音和描述数据,我们希望让我们的检索,从我们的API中检索只有我们需要为我们当前的任务/视图/不管。
  这只是该技术为我们提供的众多好处的一个例子。希望在接下来的教程系列中,我们会提前看到更多这些好处。我们的 API 的查询语言,而不是我们的数据库
  需要注意的重要一点是,GraphQL 不像我们传统的 SQL 那样是一种查询语言。它是位于我们 API 前面的抽象, 不依赖于任何特定的数据库或存储引擎。
  这真的很酷。我们可以建立一个与现有服务商交互的 GraphQL 服务器,然后围绕着这个新的 GraphQL 服务器构建,而不必担心修改现有的 REST API。比较 REST 和 GraphQL
  让我们看看 RESTful 方法与 GraphQL 方法有何不同。现在,假设我们正在构建一个返回该站点上所有教程的服务,如果我们想要特定教程的信息,我们通常会创建一个 API 端点,允许我们根据 ID 检索特定教程:## A dummy endpoint that takes in an ID path parameter "http://api.tutorialedge.net/tutorial/:id"
  如果给定一个 valid ID,这将返回一个响应,看起来像这样:{   "title": "Go GraphQL Tutorial",   "Author": "Elliot Forbes",   "slug": "/golang/go-graphql-beginners-tutorial/",   "views": 1,   "key": "value" }
  现在,假设我们想创建一个小部件,列出该作者撰写的书籍 5 个帖子。我们可以点击/author/:id端点以检索该作者撰写的所有帖子,然后进行后续调用以检索前 5 个帖子中的每一个。或者,我们可以制作一个全新的端点来为我们返回这些数据。
  这两种解决方案听起来都不是特别吸引人,因为它们会创建不需要的请求量或返回过多的数据,这突出了 RESTful 方法开始出现一些裂缝的地方。
  这就是 GraphQL 发挥作用的地方。使用 GraphQL,我们可以定义我们希望在查询中返回的数据的确切结构。所以如果我们想要上面的信息,我们可以创建一个看起来像这样的查询:{     tutorial(id: 1) {         id         title         author {             name             tutorials         }         comments {             body         }     } }
  这将随后返回我们的教程、该教程的作者和一组表示该作者编写的教程的教程 ID,而无需发送额外的x多个 REST 请求来获取信息!那有多好?基本设置
  好的,现在我们对 GraphQL 以及对它的用途有了更多的了解,让我们在实践中看看它。
  我们将使用graphql-go/graphql实现在 Go 中创建一个简单的 GraphQL 服务器 。设置简单服务器
  让我们首先使用go mod init以下方法初始化我们的项目:$ go mod init github.com/elliotforbes/go-graphql-tutorial
  接下来,让我们创建一个名为main.go. 我们将从简单开始创建一个非常简单的 GraphQL 服务器,它具有一个非常简单的解析器:// credit - go-graphql hello world example package main  import (     "encoding/json"     "fmt"     "log"      "github.com/graphql-go/graphql" )  func main() {     // Schema     fields := graphql.Fields{         "hello": &graphql.Field{             Type: graphql.String,             Resolve: func(p graphql.ResolveParams) (interface{}, error) {                 return "world", nil             },         },     }     rootQuery := graphql.ObjectConfig{Name: "RootQuery", 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)     }      // Query     query := `         {             hello         }     `     params := graphql.Params{Schema: schema, RequestString: query}     r := graphql.Do(params)     if len(r.Errors) > 0 {         log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)     }     rJSON, _ := json.Marshal(r)     fmt.Printf("%s  ", rJSON) // {"data":{"hello":"world"}} }
  现在,如果我们尝试运行它,让我们看看会发生什么:$ go run ./... {"data":{"hello":"world"}}
  所以,如果一切正常,那么我们就可以设置一个非常简单的 GraphQL 服务器并对这个服务器进行非常简单的查询。GraphQL 架构
  让我们分解上面代码中发生的事情,以便我们可以进一步扩展它。在lines 14-21我们定义我们的Schema. 当我们对我们的 GraphQL API 进行查询时,我们基本上定义了我们想要返回给我们的对象上的哪些字段,因此我们必须在我们的 Schema 重新定义这些字段。
  在 上line 17,我们定义了一个解析器函数,每当field请求此特定内容时就会触发该解析器函数。现在,我们只是返回字符串 "world",但我们将实现从这里查询数据库的能力。查询
  让我们看一下main.go文件的第二部分。在line 30我们开始定义query请求领域hello。
  然后我们创建一个params结构,其中包含对我们定义的Schema以及我们的RequestString请求的引用 。
  最后,在line 36我们执行请求并将请求的结果填充到r. 然后我们进行一些错误处理,然后将响应编组为 JSON 并将其打印到我们的控制台上。一个更复杂的例子
  现在我们已经启动并运行了一个非常简单的 GraphQL 服务器,并且我们能够对其进行查询,让我们更进一步,构建一个更复杂的示例。
  我们将创建一个 GraphQL 服务器,它返回一系列内存中的教程及其作者,以及对这些特定教程的任何评论。
  让我们定义一些struct代表 a Tutorial、 anAuthor和 a 的"s Comment:type Tutorial struct {     Title    string     Author   Author     Comments []Comment }  type Author struct {     Name      string     Tutorials []int }  type Comment struct {     Body string }
  然后我们可以创建一个非常简单的populate()函数,它将返回一个类型数组Tutorial:func populate() []Tutorial {     author := &Author{Name: "Elliot Forbes", Tutorials: []int{1}}     tutorial := Tutorial{         ID:     1,         Title:  "Go GraphQL Tutorial",         Author: *author,         Comments: []Comment{             Comment{Body: "First Comment"},         },     }      var tutorials []Tutorial     tutorials = append(tutorials, tutorial)      return tutorials }
  这将为我们提供一个简单的教程列表,然后我们可以稍后解决。创建新的对象类型
  我们将从使用 GraphQL 创建一个新对象开始graphql.NewObject()。我们将使用 GraphQL 的严格类型定义 3 种不同的类型,它们将与structs我们已经定义的 3 种相匹配。
  我们的Commentstruct 可以说是最简单的,它只包含一个 string Body,所以我们可以commentType很容易地将其表示为:var commentType = graphql.NewObject(     graphql.ObjectConfig{         Name: "Comment",         // we define the name and the fields of our         // object. In this case, we have one solitary         // field that is of type string         Fields: graphql.Fields{             "body": &graphql.Field{                 Type: graphql.String,             },         },     }, )
  接下来,我们将处理该Author结构并将其定义为一个新的 graphql.NewObject(). 这会稍微复杂一些,因为它既有一个 String字段,也有一个Int值列表,这些值代表他们编写的教程的 ID。var authorType = graphql.NewObject(     graphql.ObjectConfig{         Name: "Author",         Fields: graphql.Fields{             "Name": &graphql.Field{                 Type: graphql.String,             },             "Tutorials": &graphql.Field{                 // we"ll use NewList to deal with an array                 // of int values                 Type: graphql.NewList(graphql.Int),             },         },     }, )
  最后,让我们定义我们的tutorialTypewhich 将封装 an author和comment"s的数组以及 anID和 a title:var tutorialType = graphql.NewObject(     graphql.ObjectConfig{         Name: "Tutorial",         Fields: graphql.Fields{             "id": &graphql.Field{                 Type: graphql.Int,             },             "title": &graphql.Field{                 Type: graphql.String,             },             "author": &graphql.Field{                 // here, we specify type as authorType                 // which we"ve already defined.                 // This is how we handle nested objects                 Type: authorType,             },             "comments": &graphql.Field{                 Type: graphql.NewList(commentType),             },         },     }, ) 更新我们的架构
  现在我们已经定义了我们的Type系统,让我们着手更新我们的 Schema 以反映这些新类型。我们将定义 2 个 distinct Field,第一个将是我们的tutorial字段,它允许我们Tutorials 根据传入查询的 ID检索个人。第二个将是一个list字段,它将允许我们检索Tutorials我们在内存中定义的完整数组。    // Schema     fields := graphql.Fields{         "tutorial": &graphql.Field{             Type:        tutorialType,             // it"s good form to add a description             // to each field.             Description: "Get Tutorial By ID",             // We can define arguments that allow us to             // pick specific tutorials. In this case             // we want to be able to specify the ID of the             // tutorial we want to retrieve             Args: graphql.FieldConfigArgument{                 "id": &graphql.ArgumentConfig{                     Type: graphql.Int,                 },             },             Resolve: func(p graphql.ResolveParams) (interface{}, error) {                 // take in the ID argument                 id, ok := p.Args["id"].(int)                 if ok {                     // Parse our tutorial array for the matching id                     for _, tutorial := range tutorials {                         if int(tutorial.ID) == id {                             // return our tutorial                             return tutorial, nil                         }                     }                 }                 return nil, nil             },         },         // this is our `list` endpoint which will return all         // tutorials available         "list": &graphql.Field{             Type:        graphql.NewList(tutorialType),             Description: "Get Tutorial List",             Resolve: func(params graphql.ResolveParams) (interface{}, error) {                 return tutorials, nil             },         },     }
  所以我们已经创建了我们的类型并更新了我们的 GraphQL 模式,我们做得还不错!测试它的工作原理
  让我们尝试使用我们的新 GraphQL 服务器并处理我们提交的查询。让我们来尝试我们的list架构改变query ,我们已经在我们得到main()的功能:// Query query := `     {         list {             id             title             comments {                 body             }             author {                 Name                 Tutorials             }         }     } `
  让我们分解一下。所以在我们的查询中,我们有一个特殊的root对象。然后我们在其中说我们想要该list对象上的字段。在返回的名单list,我们希望看到的id,title,comments和 author。
  当我们运行它时,我们应该会看到以下输出:$ go run ./... {"data":{"list":[{"author":{"Name":"Elliot Forbes","Tutorials":[1]},"comments":[{"body":"First Comment"}],"id":1,"title":"Go GraphQL Tutorial"}]}}
  正如我们所见,我们的查询以 JSON 格式返回了我们所有的教程,看起来非常像我们初始查询的结构。
  现在让我们尝试对我们的tutorial模式进行查询:query := `     {         tutorial(id:1) {             title             author {                 Name                 Tutorials             }         }     } `
  再一次,当我们运行它时,我们应该看到它已经成功地检索了内存中的单独教程ID=1:$ go run ./... {"data":{"tutorial":{"author":{"Name":"Elliot Forbes","Tutorials":[1]},"title":"Go GraphQL Tutorial"}}}
  完美,看起来我们已经让list我们的tutorial模式和我们的模式都按预期工作了。
  挑战 -尝试更新我们populate() 函数中的教程列表,以便它返回更多教程。完成此操作后,请尝试使用查询并尝试对它们更加熟悉。结论
  这就是我们将在这个初始教程中介绍的全部内容。我们已经成功地设置了一个简单的 GraphQL 服务器,该服务器由内存数据存储支持。
  在下一个教程中,我们将研究 GraphQL 突变并更改我们的数据源以使用 SQL 数据库

一点资讯胡蝶内容留温,共生共赢10月26日,为期三天的第26届中国国际广告节中国网络领军品牌2020黄金资源推介会正式拉开帷幕。会议汇聚了中外知名广告公司强势媒体广告主等数百家企业。会上一点资讯品牌营销负责人胡工作时间私人订制,收入分成还更高,曹操出行司机职位有多香?2020新年伊始,全国进入特殊时期,为了最大程度上阻止病毒传播,众多企业鼓励soho办公。如今随着科学防控成效显现,全国各地开始陆续启动复工,随着返工潮来袭,大众出行需求也将开始复2019GisMyGait首届奔驰G系列川渝车友联合年会圆满落幕12月14日15,2019GisMyGait首届MercedesBenzG系列川渝车友联合年会在中国四川阆中圆满落幕,来自川渝两地MercedesBenzG系列的车友共计八十余人参2019GisMyGait首届奔驰G系列川渝车友联合年会圆满落幕12月14日15,2019GisMyGait首届MercedesBenzG系列川渝车友联合年会在中国四川阆中圆满落幕,来自川渝两地MercedesBenzG系列的车友共计八十余人参龙湖济南奥体天街提前封顶CBD商圈繁华演进据多家媒体报道,本月26日济南市政府召开新闻发布会,发布一系列支持CBD自贸区运营山东首家全球商品贸易馆的若干政策,自此CBD自贸区也成为了山东首个落地的自贸区。而今天我们也迎来了硬核操作!这个五月2000商户齐送优惠春光明媚的五一小长假说来就来真是挡都挡不住闭关已久的大家肯定是逛chi逛chi逛到哪潇洒到哪什么?钱包瘪瘪潇洒不起来?别急,今天就给大家介绍一波拿优惠的硬核操作笑容货币机用笑容换钱亲身体验叮咚课堂少儿英语课前课中课后全面测评今天刚参加完孩子学校的亲子英语角活动,小孩的表现不错,词汇短语张口就来,令人惊喜。对比一年前的亲子英语角活动,孩子的确成长了很多,再回想一下最近一周以来,孩子爸也夸奖过他的口语水平荣耀V30来啦,荣耀制噪者解锁5G音乐新玩法昨天下午,5G标杆荣耀V30系列正式面世,万众瞩目的时刻终于来临!搭载强悍的5G芯片麒麟990,惊艳众人的MatrixCamera相机矩阵技术,双超级快充,荣耀5G智慧全场景将通往养兔的未来在哪里?如果你是一位养兔人,一定要把这个视频看完,也许会改变你的一些想法!究竟,养兔子有没有未来?这个问题,一直是我们所有兔友最大的疑惑。养兔挣钱的,会告诉你养兔投资小收益快,是最值得选择浙江互联网公司想要办理ICP经营许可证为什么这么难?浙江ICP经营许可证究竟有多难办理?在上个月有一位网友私信与我交流说为什么浙江icp经营许可证这么难办理,而且还听说不找关系根本办不下来。其实事实上,并不是这样的,虽然在浙江那边I看北京车展来顺义买车,享千万钜惠,顺义汽车消费季正式拉开帷幕2020年全球唯一的顶级国际车展,第十六届北京国际车展将于顺义区中国国际展览中心新馆进行展览,伴随着北京国际车展的到来,9月23日,顺义汽车消费季正式拉开帷幕。记者从启动仪式上获悉
WEY玛奇朵诠释传承与创新日前,新一代混动SUVWEY玛奇朵正式发布官图,预示着WEY品牌智能混动时代即将到来。玛奇朵基于WEY品牌家族先锋张力美学概念,塑造未来科技感,同时又以敏锐青春的产品设计理念标签,此消彼长的ikbc时光机F108ikbc是国内CHERRY轴键盘最热销的品牌之一,也是OEM机械的代表品牌,它受台湾Ducky的影响,在品牌亮相之初,最打动人的除了PBT双色键帽,还是它的大键手感。一直以来,一个如何看待硬核式升级的雷蛇巴塞利斯蛇V2巴塞利斯蛇是近几年雷蛇主打的纯右手鼠标之一,它是针对罗技G502在300元价位针锋相对的产品。HERO引擎的加持也一度让G502优势明显,续写重型武器的神传奇。直到雷蛇等来了原相联罗技GHUB更新GPW狗屁王固件GPW狗屁王(GPROWIRELESS),是罗技最成功的高端鼠标,一度集各种黑科技于一身,无线性能握感和操控几乎没有软肋,是难以超越的存在。前阵子推出粉色版,最近发现GHUB也做了拆解从芯复生的罗技MX518LEGENDARY在HERO引擎取得成功之后,罗技逐步将各个级别的HERO引擎普及到相应的产品上,2018年10月,这项福利轮到了罗技的传奇鼠标曾一度与微软IE3。0齐名的MX518,有趣的是差不多罗技HERO12K战力测试,G304哪个DPI最准不记得什么时候,但一定是从G304开始,无线游戏鼠标的稳定性续航不再成为我们的困扰,由LIGHTSPEED无线技术和HERO12K引擎打造了G304超神的存在,而且价格也向消费者频TRUEMOVECORE核心,赛睿RIVAL3拆解过去,国外品牌但凡要出对称机身的鼠标,往往侧键都是对称的,即真正意义上的对称鼠标,左右手通用,反而一些随意的国产品牌则是更早选择对称机身右手鼠标的。不过,现在老外们也不那么固执了,特色民宿带动乡村旅游热飞猪莫干山民宿套餐预订量同比涨6倍随着暑期旅游进入预订高峰,特色民宿带动的乡村旅游热成为市场新亮点。以避暑及休闲度假著称的浙江省德清县莫干山目的地热度持续攀升。据飞猪平台,近一个月,莫干山民宿套餐预订量同比涨6倍。矿视界译文Chia矿池正式上线,矿工需要注意哪些事情?7月7日,Chia官方正式发布其矿池协议1。2。0版。该版本的发布标志着全新绘图(plots)格式的出现即可移植绘图(portableplots)。可移植和非可移植绘图有何不同?不热门的洞洞鼠标是从这里开始的,但它却不火游戏鼠标轻量化的趋势日益明显,罗技雷蛇都在守住底线的前提下想办法(如结构优化PCB设计优化和背光件减少)让鼠标更轻巧同样好用,比如GPW毒蝰这样的鼠标,这是专业厂商的思路。却也有些其实它和MASTER是一对办公室CP,罗技K845简评在罗技外设发烧友中当属G系列产品呼声最高,其实在办公领域罗技也有很高的建树,受众群体数量远超游戏系列。不过办公机械键盘一直是罗技一块短板,虽然目前办公键盘主要以薄膜键盘为主,受到游