graphql
에서 edge
(또는 realtionship
)에 filter
(또는 input
, where
)를 넣고 싶다.
예를 들면, 다음과 같다. (코드 출처: https://keystonejs.com/docs/guides/filters#filtering-related-items)
{
# Only return people who have no high-priority, incomplete tasks
people(where: {
tasks: {
none: {
priority: { equals: high },
isComplete: { equals: false }
}
}
}) {
id
name
# For each person, get tasks that are not complete
tasks(where: {
isComplete: { equals: false }
}) {
id
label
}
}
}
잘 보면, people
뿐만 아니라, people
과 연결되어있는 task
에도 where
절이 넣어졌음을 확인할 수 있다.
golang
에서 graphql
을 이용하려면 여러 가지 방법이 있을 것이다. 그 중 하나로 entgo
와 gqlgen
을 활용한다.
주의할 점은 pkg/ent/schema
에 정의되어있어야 한다는 것이다.
(출처 : https://gqlgen.com/#using-explicit-resolvers)
models:
Person:
fields:
Task:
resolver: true
여기서 주의할 점은, 확장
이라는 것이다. 따라서 기존 스키마 필드에 정의된 이름과 충돌되면 안된다.
extend type Person {
tasksWhere(where: TaskWhereInput): [Task!]!
}
extended.resolver.go
를 보면 다음 코드가 생성될 것이다.
잘 보면 리시버가 queryResolver
나 resolver
가 아님을 확인할 수 있다.
func (r *personResolver) TasksWhere(
ctx context.Context,
obj *ent.Person,
where *ent.TaskWhereInput,
) ([]*ent.Task, error) {
return nil,nil
}
where.Filter()
기능을 활용하면, 프론트엔드에서 사용된 where predicate
를 그대로 가져올 수 있다.
(참고 : https://entgo.io/docs/tutorial-todo-gql-filter-input#usage-as-predicates)
func (r *personResolver) TasksWhere(
ctx context.Context,
obj *ent.Person,
where *ent.TaskWhereInput,
) ([]*ent.Task, error) {
query := obj.QueryTasks()
query, _ = where.Filter(query)
// Execute the query and return the results
return query.All(ctx)
}