读芯术 Facebook:如何在Golang中搭建GraphQL?( 二 )


读芯术 Facebook:如何在Golang中搭建GraphQL?
文章图片
【读芯术 Facebook:如何在Golang中搭建GraphQL?】使用以下示例GraphQL查询:
读芯术 Facebook:如何在Golang中搭建GraphQL?
文章图片
灵活性
来看一个案例:如何获取书籍详细信息 。 在网络视图上 , 我想展示书籍详细信息 , 例如名称、价格和介绍 。 在RESTAPI中需要创建一个新的端点以返回名称、价格、介绍等的书籍详细信息 。
读芯术 Facebook:如何在Golang中搭建GraphQL?
文章图片
如果在移动端查看时 , 只想展示图书详细信息中的名称和价格怎么办?如果使用与Web视图相同的端点 , 则会浪费介绍的数据 。 所以需要更改该端点内部的现有逻辑 , 或创建一个新的端点 。
读芯术 Facebook:如何在Golang中搭建GraphQL?
文章图片
与RESTAPI不同 , GraphQL中仅使用一个端点即可按照Web或移动设备的需求返回书籍详细信息 。 在GraphQL中 , 只需更改查询 。
维护简单 , 易于使用
·RestAPI:如果客户端需要其他数据 , 通常需要添加一个新端点或更改一个现有端点 。
·GraphQL:客户只需要更改查询 。
缺点
·处理文件上传:GraphQL规范中没有关于文件上传的内容 , 并且突变不接受参数中的文件 。
·简单的API:如果你的API非常简单 , 那GraphQL只会使其复杂 , 所以使用RESTAPI可能会更好 。
代码实现
实现过程使用了Golang编程语言 , 这里是项目架构:
读芯术 Facebook:如何在Golang中搭建GraphQL?
文章图片
在依赖版本和依赖管理功能上使用的是go模块 。 用graphql-go来支持查询、突变和订阅;用graphql-go-handler来支持处理器 。 此时 , 我将创建一个简单的程序 , 这里使用GraphQL为详细书目创建CRUD 。 步骤如下:
先新建一个环境文件夹 , 然后新建一个名为connection.yml的文件:
app:name:"GraphQLTest"debug:trueport:"8080"host:"localhost"service:"http"context:timeout:2databases:mongodb:name:"local_db"connection:"mongodb://root:root@localhost:27017"
然后创建一个架构文件夹 , 创建名为databaseConfiguration.go、environmentConfiguration.go和model.go的文件 。 这个文件夹用来配置数据库并从connection.yml读取数据 。
databaseConfiguration.go
packageinfrastructureimport("context""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options""log")varMongodb*mongo.Databasefunc(e*Environment)InitMongoDB()(db*mongo.Database,errerror){clientOptions:=options.Client().ApplyURI(e.Databases["mongodb"].Connection)client,err:=mongo.Connect(context.TODO(),clientOptions)err=client.Ping(context.TODO(),nil)iferr!=nil{returndb,err}Mongodb=client.Database(e.Databases["mongodb"].Name)log.Println("MongodbReady!!!")returndb,err}
environmentConfiguration.go
packageinfrastructureimport("io/ioutil""log""os""path""runtime""gopkg.in/yaml.v2")func(env*Environment)SetEnvironment(){_,filename,_,_:=runtime.Caller(1)env.path=path.Join(path.Dir(filename),"environment/Connection.yml")_,err:=os.Stat(env.path)iferr!=nil{panic(err)return}}func(env*Environment)LoadConfig(){content,err:=ioutil.ReadFile(env.path)iferr!=nil{log.Println(err)panic(err)}err=yaml.Unmarshal([]byte(string(content)),env)iferr!=nil{log.Println(err)panic(err)}ifenv.App.Debug==false{log.SetOutput(ioutil.Discard)}log.Println("Configloadsuccessfully!")return}