gqlgen에서 생성된 구조에 사용자 정의 디렉터리에 지정한 임의의 태그를 설정합니다
directive @tag(
validate: String
) on INPUT_FIELD_DEFINITION
input NewUser {
email: String! @tag(validate: "required,email")
password: String! @tag(validate: "required,max=50")
name: String! @tag(validate: "required,max=50")
}
이런 모형을 만들고 싶어요.type NewUser struct {
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,max=50"`
Name string `json:"name" validate:"required,max=50"`
}
modelgen.Plugin의 MutaateHook을 사용해 해시태그를 설정한 레시피가 기재돼 있기 때문에 이를 바탕으로 맞춤 제작이 이뤄진다.원본 코드에서는 모델의 필드 정보만 참조할 수 있기 때문에 패턴 파일에 정의된 정보를 얻어야 한다
fd *ast.FieldDefinition = cfg.Schema.Types[model.Name].Fields[i]
이 정보를 얻을 수 있으면 필드 정의에서 지시를 받고 식단과 같은 방식field.Tag
으로 보충한다.//go:build ignore
package main
import (
"fmt"
"os"
"github.com/99designs/gqlgen/api"
"github.com/99designs/gqlgen/codegen/config"
"github.com/99designs/gqlgen/plugin"
"github.com/99designs/gqlgen/plugin/modelgen"
"github.com/vektah/gqlparser/v2/ast"
)
func fieldHook(f *modelgen.Field, fd *ast.FieldDefinition) {
// @tagディレクティブ
directive := fd.Directives.ForName("tag")
if directive != nil {
// validateタグを追加
validateTag := directive.Arguments.ForName("validate")
if validateTag != nil {
f.Tag += fmt.Sprintf(` validate:"%s"`, validateTag.Value.Raw)
}
}
}
func main() {
cfg, err := config.LoadConfigFromDefaultLocations()
if err != nil {
fmt.Fprintln(os.Stderr, "failed to load config", err.Error())
os.Exit(2)
}
// Attaching the mutation function onto modelgen plugin
p := modelgen.Plugin{
MutateHook: func(b *modelgen.ModelBuild) *modelgen.ModelBuild {
for _, model := range b.Models {
for i, field := range model.Fields {
fieldHook(field, cfg.Schema.Types[model.Name].Fields[i])
}
}
return b
},
}
// ディレクティブとしては使用しないのでコードに出力されないように設定
// https://github.com/99designs/gqlgen/blob/v0.14.0/codegen/config/config.go#L231
cfg.Directives["tag"] = config.DirectiveConfig{
SkipRuntime: true,
}
err = api.Generate(cfg,
func(cfg *config.Config, plugins *[]plugin.Plugin) {
for i, plugin := range *plugins {
if _, ok := plugin.(*modelgen.Plugin); ok {
// modelgen.Pluginを置き換える
(*plugins)[i] = &p
}
}
},
)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(3)
}
}
이 동작을 적당한 곳에서 실행하면 라벨이 설정된 모델을 생성합니다.go run cmd/gqlgen/gen.go
를 점으로 하고 원형을 유지하면 지시 코드로 생성하기 때문에 @goField
와 같이 코드를 생성하지 않아야 한다.cfg.Directives["tag"] = config.DirectiveConfig{
SkipRuntime: true,
}
또한 원시 코드를 유지한다err = api.Generate(cfg,
api.NoPlugins(),
api.AddPlugin(&p),
)
라면 모델만 생성하기 때문에 잘 바꿀 수 있는 방법을 찾아보았으나 찾을 수 없어 이미 유형 변환이 진행된 모델을 교체해 봤다.이 예에서는
validate
에만 대응하지만 아래 부분과 같은 방식으로 진행하면 임의의 형식으로 진행할 수 있다.// validateタグを追加
validateTag := directive.Arguments.ForName("validate")
if validateTag != nil {
f.Tag += fmt.Sprintf(` validate:"%s"`, validateTag.Value.Raw)
}
Reference
이 문제에 관하여(gqlgen에서 생성된 구조에 사용자 정의 디렉터리에 지정한 임의의 태그를 설정합니다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/achamaro/articles/d1360c6d1e39fe텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)