Hello World - 2022年3月
type: channel
link: https://wlwl.host/index.php/2022/03/
description: Just So So ...
items: Go GraphQL入门

Go GraphQL入门
type: item
date: 2022-03-06T15:06:00+00:00
description: 为API而生（而不是为数据库而生）的查询语言，GraphQL不是一个和传统SQL一样的查询语言，它是位于API之前的一层抽象，且并不依赖于任何特定的数据或存储引擎。REST和GraphQL的区别首先，让我们看看RESTful方法和GraphQL方法的区别。想象下我们正在构建一个能返回本站所有教程的服务，如果我们需要某些指定的教程信息，通常来说，我们会创建一个API端点以允许我们以一个ID来检索指定的教程。# A dummy endpoint that takes in an ID path parameter 'http://api.tutorialedge.net/tutorial/:id'如果给定的是一个合法的 ID ，它将会返回一个响应体，该响应体可能会如下所示：{ "title": "Go GraphQL Tutorial", "Author": "Elliot Forbes", "slug": "/golang/go-graphql-beginners-tutorial/", "views": 1, "key" : "value" }现在，假设我们想显示一个列表，列出指定的作者撰写的前5个帖子。我们可以使用/author/:id这样的API来检索出所有由该作者撰写的帖子，然后再执行后续的调用获取排名前5的帖子。亦或者，我们可以创建一个新的API来返回这些数据。上述的解决方案听起来并没有什么特别之处，因为它们创建了大量无用的请求或者返回了过多的冗余信息，这也暴露了RESTful方法的一些缺陷。此时，就轮到 GraphQL 入场了。通过 GraphQL ，我们可以在查询中精确定义我们想要返回的数据。因此，如果我们需要上述的教程信息，我们可以创建一个查询，如下所示：{ tutorial(id: 1) { id title author { name tutorials } comments { body } } }随后，它就会返回该教程的作者信息以及指定id教程下该作者所撰写的其他教程列表。这些数据都是我们所需的，但却不用通过发送额外的REST请求来获得快速开始创建一个包含以下内容的文件：main.gopackage main import ( "log" "net/http" graphql "github.com/graph-gophers/graphql-go" "github.com/graph-gophers/graphql-go/relay" ) type query struct{} func (_ *query) Hello() string { return "Hello, world!" } func main() { s := ` type Query { hello: String! } ` schema := graphql.MustParseSchema(s, &query{}) http.Handle("/query", &relay.Handler{Schema: schema}) log.Fatal(http.ListenAndServe(":8080", nil)) }使用go运行该程序go run main.go使用curl测试查看结果curl -XPOST -d '{"query": "{ hello }"}' localhost:8080/query将会输出{"data":{"hello":"Hello, world!"}}一般流程1. 定义schemaconst schema string = ` scalar Long schema { query: Query } # 以太坊区块 type Block { number: Long! hash: String! nonce: Long! timestamp: Long! difficulty: Long! } type Query { block(number: Long, hash: String): Block } `参考官方入门文档2. 自定义类型解码接口实现（如果有）type Long uint64 // ImplementsGraphQLType returns true if Long implements the provided GraphQL type. func (b Long) ImplementsGraphQLType(name string) bool { return name == "Long" } // UnmarshalGraphQL unmarshals the provided GraphQL query data. func (b *Long) UnmarshalGraphQL(inpu…