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)
}