在 golang 中構建 GraphQL 服務器 ggenql


官方文檔地址 :https://gqlgen.com/getting-started/

本教程將帶您完成使用 gqlgen 構建 GraphQL 服務器的過程,該服務器可以:

  • 返回待辦事項列表
  • 創建新的待辦事項
  • 在待辦事項完成時標記它們

您可以在此處找到本教程的完成代碼

設置項目

為您的項目創建一個目錄,並將其初始化為 Go Module:

$ mkdir gqlgen-todos
$ cd gqlgen-todos $ go mod init github.com/[username]/gqlgen-todos $ go get github.com/99designs/gqlgen 

構建服務器

創建項目骨架

$ go run github.com/99designs/gqlgen init

這將創建我們建議的包布局。如果需要,您可以在 gqlgen.yml 中修改這些路徑。

├── go.mod
├── go.sum
├── gqlgen.yml               - The gqlgen config file, knobs for controlling the generated code.
├── graph
│   ├── generated            - A package that only contains the generated runtime
│   │   └── generated.go
│   ├── model                - A package for all your graph models, generated or otherwise
│   │   └── models_gen.go
│   ├── resolver.go          - The root graph resolver type. This file wont get regenerated
│   ├── schema.graphqls      - Some schema. You can split the schema into as many graphql files as you like
│   └── schema.resolvers.go  - the resolver implementation for schema.graphql
└── server.go                - The entry point to your app. Customize it however you see fit

定義您的架構

gqlgen 是一個模式優先的庫——在編寫代碼之前,你使用 GraphQL模式定義語言來描述你的 API 默認情況下,這會進入一個名為的文件, schema.graphql但您可以根據需要將其分解為多個不同的文件。

為我們生成的模式是:

type Todo {  id: ID!  text: String!  done: Boolean!  user: User! }  type User {  id: ID!  name: String! }  type Query {  todos: [Todo!]! }  input NewTodo {  text: String!  userId: String! }  type Mutation {  createTodo(input: NewTodo!): Todo! }

實現解析器

執行時,gqlgen 的generate命令將模式文件 ( graph/schema.graphqls) 與模型進行比較graph/model/*,並且,只要可能,它將直接綁定到模型。這已經在init運行時完成了我們將在本教程的后面編輯模式,但現在,讓我們看看已經生成的內容。

如果我們看一看,graph/schema.resolvers.go我們將看到 gqlgen 無法匹配它們的所有時間。對我們來說是兩次:

func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { panic(fmt.Errorf("not implemented")) } func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { panic(fmt.Errorf("not implemented")) } 

我們只需要實現這兩個方法來讓我們的服務器工作:

首先我們需要一個地方來跟蹤我們的狀態,讓我們把它放在graph/resolver.gograph/resolver.go文件是我們聲明應用程序依賴項的地方,例如我們的數據庫。server.go當我們創建圖形時,它會被初始化一次

type Resolver struct{ todos []*model.Todo } 

回到graph/schema.resolvers.go,讓我們實現那些自動生成的解析器函數的主體。對於CreateTodo,我們將使用math.rand隨機生成的 ID 簡單地返回一個待辦事項,並將其存儲在內存中的待辦事項列表中——在實際應用中,您可能會使用數據庫或其他一些后端服務。

func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { todo := &model.Todo{ Text: input.Text, ID: fmt.Sprintf("T%d", rand.Int()), User: &model.User{ID: input.UserID, Name: "user " + input.UserID}, } r.todos = append(r.todos, todo) return todo, nil } func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { return r.todos, nil } 

運行服務器

我們現在有一個工作服務器,可以啟動它:

go run server.go

在瀏覽器中打開 http://localhost:8080。以下是一些要嘗試的查詢,從創建待辦事項開始:

mutation createTodo {  createTodo(input: { text: "todo", userId: "1" }) {  user {  id  }  text  done  } }

然后查詢它:

query findTodos {  todos {  text  done  user {  name  }  } }

不要急切地獲取用戶

這個例子很棒,但在現實世界中獲取大多數對象的成本很高。我們不想在待辦事項上加載用戶,除非用戶確實要求它。所以讓我們用Todo更真實的東西替換生成的模型。

創建一個名為的新文件 graph/model/todo.go

package model type Todo struct { ID string `json:"id"` Text string `json:"text"` Done bool `json:"done"` UserID string `json:"user"` } 

筆記

默認情況下,gqlgen 將使用模型目錄中與名稱匹配的任何模型,這可以在gqlgen.yml.

並運行go run github.com/99designs/gqlgen generate

現在,如果我們查看,graph/schema.resolvers.go我們可以看到一個新的解析器,讓我們實現它並修復CreateTodo.

func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { todo := &model.Todo{ Text: input.Text, ID: fmt.Sprintf("T%d", rand.Int()), UserID: input.UserID, // fix this line  } r.todos = append(r.todos, todo) return todo, nil } func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, error) { return &model.User{ID: obj.UserID, Name: "user " + obj.UserID}, nil } 

收尾工作

在我們的resolver.gopackage之間import,添加以下行:

//go:generate go run github.com/99designs/gqlgen 

這個神奇的注釋告訴go generate我們要重新生成代碼時要運行的命令。要在整個項目中遞歸運行 go generate,請使用以下命令:

go generate ./...

失敗 執行 go get github.com/99designs/gqlgen/cmd@v0.14.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM