가능한 한 통속적이고 알기 쉽게 강좌를 해설하다
개시하다
두 번째 엔지니어 인턴십으로 골랑+그래픽QL로 개발하기로 했다.
요즘은 이해가 늘었지만 지금까지 REST 이외의 세계를 몰랐던 제게 Gqlgen이 뭘 해줄지, 뭐가 편할지 전혀 두서가 없어서 같은 상황에 처한 사람들을 위해 기사를 쓰고 싶습니다.
전제 지식
무엇이 gqlgen입니까?
공식을 인용하다
gqlgen is a Go library for building GraphQL servers without any fuss.
・gqlgen is based on a Schma first aproach—You get to Define your API using the GraphiQL Schema Definition Language.
・gqlgen prioritizes Type safety—You should never see map〔string〕interface{}here.
・gqlgen enables Codegen—We generate the boring bits,so you can focus on building your app quickly.
어쨌든 GraphiQL 서버를 제작할 때'모드 우선'에서'유지형 안전성','자동 생성 코드'의 Golang의 프로그램 라이브러리를 사용할 수 있다.
목표
gqlgen 튜토리얼에 따라 간단한 todo 프로그램을 만듭니다.동작은 GraphiQL Playround 확인 형식으로 수행됩니다.
이번 코드.
Let's start!
일단 준비부터.작업 목록을 만들고 goo의 개발 환경을 조정합시다.이번에 사용
golang 1.18
.mkdir gqlgen_tutorial && cd gqlgen_tutorial
go mod init gqlgen_tutorial
에 이어 이번 주인공 gqlgen 포장과 의존 관계를 담은 내용을 다운로드한다.go get -u github.com/99designs/[email protected]
최신 버전의 0.17.5를 사용합니다.그러면 다음 명령으로 모형 파일을 만듭니다.
go run github.com/99designs/gqlgen init
GraphiQL 서버를 아주 간단하게 만들었습니다!디렉토리 구성은 다음과 같이 정상적입니다.파일 생성에 대한 설명
이 파일은 GraphiQL 서버의 요청
graph/resolver.go
에 대해 설명하고 적절한 방법으로 부르는 역할을 했다.schema가 정의한 type과 input을 Golang으로 변환하는 구조체를 정의했습니다.
요청에 따라 실제 처리
resolver
된 서류를 실시한다.go run github.com/99designs/gqlgen generate
코드를 실행한 후에 생성된 것이다.선언은 뿌리로서의 Resolver 구조체이다.다시는 태어나지 않을 겁니다.
GraphiQL 모드를 정의하는 파일입니다.이 파일을 토대로 다른 파일을 다시 생성합니다.
gqlgen 설정 파일입니다.이번엔 안 하지만 shcema의 분할 등 설정도 이 파일로 할 수 있다.
graph/schema.graphqls
봅시다.# GraphQL schema example
#
# https://gqlgen.com/getting-started/
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!
}
기억하지 못하는 scheme가 생성되었다.gqlgen에서 기본적으로 생성된 것입니다.이번에는 이 schema를 바탕으로 간단한 todo 앱을 만들고 싶습니다.글의 첫머리에서도 gqlgen은 모델로 우선적으로GraphiQL 서버를 생성한다고 언급했다.코드를 자동으로 생성하거나 Resolver (후술) 를 실행할 때도 이 모드에서 실현됩니다.뜻밖의 오류가 있을 때 이 schema에서 확인하는 것이 좋습니다.
아래를 보시오
graph/model/models_gen.go
.// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package model
type NewTodo struct {
Text string `json:"text"`
UserID string `json:"userId"`
}
type Todo struct {
ID string `json:"id"`
Text string `json:"text"`
Done bool `json:"done"`
User *User `json:"user"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
방금 본 schema에서 정의한Query와 Mutation 이외의 유형은 구조체로 정의됩니다.이 파일의 구조체를 사용해서 다음에 설명한 Resolver를 실행합니다.마지막으로 보시죠
graph/schema.resolver.go
.package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
import (
"context"
"fmt"
"gqlgen_tutorial/graph/generated"
"gqlgen_tutorial/graph/model"
)
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"))
}
// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
이상한 방법이 생겼어요.주의해야 할 것은 CreateTodo
와 Todos
이다.이것은 graph/schema.graphqls
에서 정의한 것이다type Query {
todos: [Todo!]!
}
...省略
type Mutation {
createTodo(input: NewTodo!): Todo!
}
는 각각 이쪽에 대응한다.gqlgen에서 GraphiQL 서버에 대한 요청/generated/generated.go
을 자동으로 생성한 후 이 방법들이 호출되었습니다.그래서 이런 방법들이 이른바 Controller
역할을 했다.지금 이 단계에서는 내용이 비어 있고 아무것도 이루어지지 않았기 때문에 지금부터 내용을 실시한다.데이터는 통상적으로 데이터베이스에 영구적으로 저장되지만 동작을 확인하기 위해 먼저 메모리에 데이터를 저장한다.
우선 변경
graph/resolver.go
.type Resolver struct {
todos []*model.Todo // 追加
}
schema.resolver.goo에서 정의한mutation Resolver와query Resolver는 모두 이 Resolver로 포장된 것이기 때문에 이 Resolver에서 todos를 유지하고 싶습니다.다음은 Resolver를 실시합니다.
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
}
CreateTodo
방법은 요청된 정보(input model.NewTodo)
에서 Todo 모형을 제작하여 Resolver struct에 추가된 todos slice 처리일 뿐이다.Todos
방법은 기존 Resolver struct 내의 todos slice만 반환합니다.실제 앱이라면 좀 더 복잡한 논리와 DB 조작이 있을 수 있지만, 이번에는 최대한 최소화하고 싶어서 사랑을 끊었다.
resolver 설치가 끝났으니까, 야 동작 확인!GraphiQL 서버를 시작합니다.
방문
go run server.go
http://localhost:8080/
하세요.이런 페이지를 보여주면 성공!GraphiQL playground를 사용하면 curl 명령을 특별히 두드리지 않고 앞부분의 동작을 확인할 수 있습니다.
당장 무테이션 요청해서 토도 만들어봐!다음 요청을 복사하면 화면 왼쪽 상단에 있는 재생 표시가 있습니까?부탁 좀 들어주세요.
mutation {
createTodo(input: { text: "todo", userId: "1" }) {
user {
id
}
text
done
}
}
아래의 답장을 답장하면 정상적으로 제작이 가능합니다!{
"data": {
"createTodo": {
"user": {
"id": "1"
},
"text": "todo",
"done": false
}
}
}
아래에서 제작한 토도를 구해 보세요.query {
todos {
text
done
user {
name
}
}
}
대박!resolver만 설치하면 GraphiQL 서버를 간단하게 만들 수 있습니다.
그러나 이 점만으로도 GraphiQL의 장점 중 하나는 얻은 데이터를 선택할 수 없다는 것이다.
예를 들어 현재 이 단계에서 todos를 얻었을 때user를 가져야 한다.당연하다
이러한 요청을 보내면user 데이터는 응답으로 되돌아오지 않지만 내부에서user 데이터를 얻었습니다.RDB를 자주 사용하는 웹 응용 프로그램에서 todo 모델은 UserID만 있고 링크된user는 대부분 todo와 달리 DB에서 얻는다.이 경우 사용자 데이터가 필요하지 않아도 sql가 필요하지 않습니다.
이러다가는 그래피큐어의 은혜를 온전히 받아들였다고 할 수는 없다.이것은 실시
todoResolver
를 통해 해결할 수 있다.여기서부터 수정해.우선 새로운 모델 제작
Todo struct
이 필요하다.현재 상태에서는 schema.graphqls
기반으로 자동 생성된 Todo 모델이 사용됩니다.그러나 이렇게 되면 mutaaionmodels/models_gen.go
의 보답치인 Todo모델은 반드시 User를 포함해야 하기 때문에 Todo모델을 새로 정의했다.다음 내용을 다시 제작
CreateTodo
하십시오.{
"data": {
"todos": [
{
"text": "todo",
"done": false,
"user": {
"name": "user 1"
}
}
]
}
}
그 다음은 gqlgen.yml 파일에 다음 내용을 추가합니다.query {
todos {
text
done
}
}
이로써'todo 모델 사용graph/models/todo.go
의 Todo struct'를 지정할 수 있다.준비되면 파일을 생성하세요.
type Todo struct {
ID string
Text string
Done bool
UserID string
}
gqlgen_tutorial/graph/model.go
를 보십시오.Todo struct가 사라졌네요.이제 방금 정의한 Todo 모델이 사용됩니다.그럼 Resolver를 실현하세요.
graph/model/models_gen.go
를 여십시오.Todo struct는 아까 변경된 내용에 따라
schema.resolvers.go
유지User
하기 때문에우선 수정
UserID
.models:
Todo:
model: gqlgen_tutorial/graph/model.Todo
이전에는 없었던 User 방법go run github.com/99designs/gqlgen generate
상기 변경 사항을 추가합니다.이게 제가 처음에 이해하기 어려웠던 점이에요.
todo struct가mutation
CreateTodo
과queryCreateTodo
에 반환되었을 때 schema의 Todos
에서 지정한 User 필드에 todo struct가 없기 때문에 todo Resolver에 대한 User 방법을 호출했습니다.이렇게 하면 완성된다.마지막 한 번 더
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, // 修正
}
r.todos = append(r.todos, todo)
return todo, nil
}
를 실행하고 GraphiQL Playground를 통해 동작을 확인하십시오.아까랑 똑같은 행동을 하면 완벽해.최후
어때?이해하기 어려운 점이 많다고 생각해요. 도움이 된다면 영광이에요.
나는 마음속으로부터 줄곧 불평과 불평을 하고 있다.
Reference
이 문제에 관하여(가능한 한 통속적이고 알기 쉽게 강좌를 해설하다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/omoterikuto/articles/a43c989ca36073텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)