gqlgen 및 Gorm을 사용하여 Go에서 GraphQL Api 빌드
31640 단어 gotutorialwebdevprogramming
소개
오늘의 튜토리얼에서는 스키마 우선 접근 방식이 있고 유형이 안전하며 여전히 codegen을 사용하여 데이터 유형과 리졸버를 생성하는 gqlgen 프레임워크를 사용하여 graphql API를 생성할 것입니다.
내가 gqlgen에 대해 가장 놀라운 점은 codegen이 구성 가능하고 매우 완전한 문서를 가지고 있으며 배우기 쉽고 기능면에서 상당히 완전하다는 것입니다.
전제 조건
계속 진행하기 전에 다음 기술에 대한 기본 지식이 있어야 합니다.
시작하기
첫 번째 단계는 프로젝트 폴더를 만드는 것입니다.
mkdir haumea
cd haumea
go mod init haumea
다음으로
gqlgen
를 사용하여 프로젝트를 초기화하겠습니다.go run github.com/99designs/gqlgen init
이제 프로젝트의 구조와 관련하여 몇 가지 변경을 할 수 있습니다.
graph/
폴더 내에서 다음 폴더와 파일을 삭제합니다.model/
- 이 폴더에는 프로젝트의 모델/데이터 유형이 있습니다resolver.go
및 schema.resolvers.go
- 이 파일은 스키마 해석기schema.graphqls
- API/프로젝트 graphql 스키마파일과 폴더를 제거한 후 이제
gqlgen.yml
파일을 편집하여 다음과 같은 구성을 추가할 수 있습니다.# @/gqlgen.yml
schema:
- graph/typeDefs/*.gql
exec:
filename: graph/generated/generated.go
package: generated
model:
filename: graph/customTypes/types_gen.go
package: customTypes
resolver:
layout: follow-schema
dir: graph/resolvers
package: graph
filename_template: "{name}.resolvers.go"
autobind:
models:
ID:
model:
- github.com/99designs/gqlgen/graphql.Int
- github.com/99designs/gqlgen/graphql.ID
- github.com/99designs/gqlgen/graphql.Int64
- github.com/99designs/gqlgen/graphql.Int32
Int:
model:
- github.com/99designs/gqlgen/graphql.Int
- github.com/99designs/gqlgen/graphql.Int64
- github.com/99designs/gqlgen/graphql.Int32
위의 구성에서 다음과 같이 변경했습니다.
typeDefs
폴더 안에 있으며 확장자는 .gql
customTypes/
라는 파일의 types_gen.go
폴더에 저장됩니다.resolvers/
폴더 안에 생성됩니다. ID
을 사용할 때 식별자(id)가 golang 데이터 유형Int
에 매핑됩니다.이를 염두에 두고 이제 오늘 프로젝트의 스키마를 생성할 수 있습니다. 먼저
typeDefs/
폴더를 생성하고 그 안에 todo.gql
파일을 생성해 보겠습니다.# @/graph/typeDefs/todo.gql
type Todo {
id: ID!
text: String!
done: Boolean!
}
input TodoInput {
id: ID!
text: String!
done: Boolean!
}
type Mutation {
createTodo(text: String!): Todo!
updateTodo(input: TodoInput!): Todo!
deleteTodo(todoId: ID!): Todo!
}
type Query {
getTodos: [Todo!]!
getTodo(todoId: ID!): Todo!
}
스키마가 생성되면 다음 단계는 쿼리 및 변형에 대한 데이터 유형 및 확인자를 생성하는 것입니다.
go run github.com/99designs/gqlgen generate
이제 이 모든 작업을 완료했으므로 데이터베이스에 대한 연결을 설정하는 다음 단계로 넘어갈 수 있습니다.
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
그런 다음
common/
파일의 데이터베이스 연결 구성을 사용하여 db.go
라는 폴더를 만들 수 있습니다.// @/graph/common/db.go
package common
import (
"haumea/graph/customTypes"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func InitDb() (*gorm.DB, error) {
var err error
db, err := gorm.Open(sqlite.Open("dev.db"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
return nil, err
}
db.AutoMigrate(&customTypes.Todo{})
return db, nil
}
데이터베이스 연결이 구성되었으므로 이제 graphql api 컨텍스트를 생성할 수 있습니다. 여전히
common/
폴더 안에 context.go
파일을 생성합니다(이 문서에서는 데이터베이스 연결만 전달하지만 컨텍스트를 쉽게 확장할 수 있음). :// @/graph/common/context.go
package common
import (
"context"
"net/http"
"gorm.io/gorm"
)
type CustomContext struct {
Database *gorm.DB
}
var customContextKey string = "CUSTOM_CONTEXT"
func CreateContext(args *CustomContext, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
customContext := &CustomContext{
Database: args.Database,
}
requestWithCtx := r.WithContext(context.WithValue(r.Context(), customContextKey, customContext))
next.ServeHTTP(w, requestWithCtx)
})
}
func GetContext(ctx context.Context) *CustomContext {
customContext, ok := ctx.Value(customContextKey).(*CustomContext)
if !ok {
return nil
}
return customContext
}
이제 API의 항목 파일로 이동하여 데이터베이스 연결을 시작하고 API 컨텍스트에서 데이터베이스를 전달해야 합니다. 이 방법:
// @/server.go
package main
import (
"haumea/common"
"haumea/graph/generated"
resolvers "haumea/graph/resolvers"
"log"
"net/http"
"os"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
)
const defaultPort = "4000"
func main() {
port := os.Getenv("PORT")
if port == "" {
port = defaultPort
}
db, err := common.InitDb()
if err != nil {
log.Fatal(err)
}
srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &resolvers.Resolver{}}))
customCtx := &common.CustomContext{
Database: db,
}
http.Handle("/", playground.Handler("GraphQL playground", "/query"))
http.Handle("/query", common.CreateContext(customCtx, srv))
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
이제 서버를 구성하고 데이터베이스 설정을 완료했으며 연결을 생성했으므로 리졸버 작업만 하면 됩니다.
각 리졸버에서 생성한 컨텍스트에 액세스하려면 CRUD를 수행하기 위해 데이터베이스 인스턴스를 가져올
GetContext()
함수를 사용합니다.// @/graph/resolvers/todo.resolvers.go
package graph
import (
"context"
"haumea/common"
"haumea/graph/customTypes"
"haumea/graph/generated"
)
func (r *mutationResolver) CreateTodo(ctx context.Context, text string) (*customTypes.Todo, error) {
context := common.GetContext(ctx)
todo := &customTypes.Todo{
Text: text,
Done: false,
}
err := context.Database.Create(&todo).Error
if err != nil {
return nil, err
}
return todo, nil
}
func (r *mutationResolver) UpdateTodo(ctx context.Context, input customTypes.TodoInput) (*customTypes.Todo, error) {
context := common.GetContext(ctx)
todo := &customTypes.Todo{
ID: input.ID,
Text: input.Text,
Done: input.Done,
}
err := context.Database.Save(&todo).Error
if err != nil {
return nil, err
}
return todo, nil
}
func (r *mutationResolver) DeleteTodo(ctx context.Context, todoID int) (*customTypes.Todo, error) {
context := common.GetContext(ctx)
var todo *customTypes.Todo
err := context.Database.Where("id = ?", todoID).Delete(&todo).Error
if err != nil {
return nil, err
}
return todo, nil
}
func (r *queryResolver) GetTodos(ctx context.Context) ([]*customTypes.Todo, error) {
context := common.GetContext(ctx)
var todos []*customTypes.Todo
err := context.Database.Find(&todos).Error
if err != nil {
return nil, err
}
return todos, nil
}
func (r *queryResolver) GetTodo(ctx context.Context, todoID int) (*customTypes.Todo, error) {
context := common.GetContext(ctx)
var todo *customTypes.Todo
err := context.Database.Where("id = ?", todoID).Find(&todo).Error
if err != nil {
return nil, err
}
return todo, nil
}
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
서버를 실행하려면 다음 명령을 사용하십시오.
go run server.go
그리고 이 프로젝트의 각 쿼리와 변형을 테스트하려면 브라우저에서 새 탭을 열고
http://localhost:4000/
를 방문하십시오.결론
늘 그렇듯이 기사가 마음에 드셨기를 바라며 기존 프로젝트에 도움이 되었거나 단순히 사용해 보고 싶으셨기를 바랍니다.
기사에서 잘못된 부분을 발견했다면 댓글로 알려주시면 수정하겠습니다. 마치기 전에 이 기사의 소스 코드에 액세스하려면 github 저장소에 대한 링크here를 남겨둡니다.
Reference
이 문제에 관하여(gqlgen 및 Gorm을 사용하여 Go에서 GraphQL Api 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/franciscomendes10866/build-a-crud-graphql-api-with-gqlgen-and-gorm-36de텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)