how to add relationship(edge) filter in graphql(feat:golang)

dasd412·2024년 8월 17일
0

실무 문제 해결

목록 보기
4/17

원하는 것

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 기준으로 만들기

golang에서 graphql을 이용하려면 여러 가지 방법이 있을 것이다. 그 중 하나로 entgogqlgen을 활용한다.

1. gqlgen.yml에 models를 추가한다.

주의할 점은 pkg/ent/schema에 정의되어있어야 한다는 것이다.

(출처 : https://gqlgen.com/#using-explicit-resolvers)

models:
  Person:
    fields:
      Task:
        resolver: true

2. extended.graphql에 기존 schema의 필드를 확장한다.

여기서 주의할 점은, 확장이라는 것이다. 따라서 기존 스키마 필드에 정의된 이름과 충돌되면 안된다.

extend type Person {
    tasksWhere(where: TaskWhereInput): [Task!]!
}

3. gqlgen을 활용하여 코드를 생성하자.

extended.resolver.go를 보면 다음 코드가 생성될 것이다.
잘 보면 리시버가 queryResolverresolver가 아님을 확인할 수 있다.

func (r *personResolver) TasksWhere(
	ctx context.Context,
	obj *ent.Person,
	where *ent.TaskWhereInput,
) ([]*ent.Task, error) {
	return nil,nil
}

4. 입맛에 맞게 커스터마이징 하자.

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

profile
시스템 아키텍쳐 설계에 관심이 많은 백엔드 개발자입니다. (Go/Python/MSA/graphql/Spring)

0개의 댓글