문서 메뉴

문서 홈Atlas App Services

사용자 지정 리졸버 정의

이 페이지의 내용

  • 개요
  • 절차
  • 새 사용자 지정 리졸버 만들기
  • 리졸버 필드 이름 정의
  • 상위 유형 정의
  • 입력 유형 정의
  • 페이로드 유형 정의
  • 리졸버 함수 정의
  • 리졸버 저장 및 배포
  • 사용자 지정 리졸버 예제
  • 시나리오 & 스키마
  • 사용자 지정 쿼리 리졸버
  • 사용자 지정 변형
  • 계산된 속성

앱의 사용 사례에 맞게 GraphQL API를 확장하는 사용자 지정 리졸버를 정의할 수 있습니다. 사용자 정의 리졸버를 사용하면 생성된 쿼리변형 리졸버보다 더 복잡하거나 특정한 새로운 루트 수준 연산을 정의할 수 있습니다. 작업에서 확장된 유형의 문서를 읽을 때마다 결과를 동적으로 평가하는 새로운 계산된 필드를 생성된 문서 유형에 추가할 수도 있습니다.

1

App Services UI의 탐색 사이드바에서 GraphQL을 클릭한 다음 Custom Resolvers 탭을 선택합니다.

Add a Custom Resolver 버튼을 클릭하여 새 사용자 지정 리졸버에 대한 구성 화면을 엽니다.

App Services UI의 사용자 지정 리졸버 화면
2

GraphQL Field Name 입력란에 리졸버에 대한 App Servicese 이름을 지정합니다. App Servicese는 이 이름을 사용하여 상위 유형에 사용자 지정 리졸버를 노출하므로 이 이름은 GraphQL API로 작업하는 개발자에게 유용한 방식으로 리졸버가 수행하는 작업을 설명해야 합니다.

3

App Servicese는 모든 사용자 지정 리졸버를 상위 유형의 필드로 노출합니다. 상위 유형은 루트 수준 쿼리 또는 변형되거나 생성된 문서 유형일 수 있습니다.

Parent Type 드롭다운에서 다음 옵션 중 하나를 선택합니다:

옵션
설명
Query

리졸버는 루트 수준 query 작업입니다:

예제

myCustomQuery라는 쿼리에 대한 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

type Query {
myCustomQuery: DefaultPayload
...
}
Mutation

리졸버는 루트 수준 mutation 작업입니다:

예제

myCustomMutation이라고 명명된 변형 항목에 대한 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

type Mutation {
myCustomMutation: DefaultPayload
...
}
Document Type

리졸버는 지정된 문서 유형에 대해 계산된 속성입니다. 문서 유형을 반환하는 모든 쿼리 또는 변형은 해당 유형에 대해 사용자 지정 리졸버가 정의한 계산된 속성을 요청할 수도 있습니다.

예제

myCustomTaskProperty라고 명명된 Task 유형의 계산된 속성을 정의하는 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

type Task {
myCustomTaskProperty: DefaultPayload
...
}
4

사용자 지정 리졸버는 수신 쿼리 또는 변형의 입력 매개 변수를 받아들일 수 있습니다. 기존에 생성된 입력 유형을 사용하거나 리졸버를 위해 특별히 새로운 사용자 지정 입력 유형을 정의할 수 있습니다.

입력 유형을 지정하는 경우 App Services는 사용자 지정 리졸버의 생성된 GraphQL 스키마 정의에서 input 매개 변수를 지정된 입력 유형을 허용하는 선택적 매개 변수로 노출합니다. 입력 유형을 지정하지 않으면 사용자 지정 리졸버가 어떤 인수도 허용하지 않습니다.

Input Type 드롭다운에서 다음 옵션 중 하나를 선택합니다:

옵션
설명
None

리졸버는 어떠한 입력도 받지 않습니다.

예제

입력을 허용하지 않는 myCustomQuery 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

type Query {
myCustomQuery: DefaultPayload
...
}
Scalar

리졸버는 생성된 GraphQL 스키마의 기존 스칼라 유형을 사용합니다.

두 번째 드롭다운 입력에서 단일 스칼라 또는 동일한 유형의 다중 스칼라 배열을 선택합니다.

예제

Scalar Type 옵션을 사용하여 DateTiem 입력 유형을 지정하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같이 스키마가 생성됩니다:

type Query {
myCustomQuery(input: DateTime): DefaultPayload
...
}
Existing Type

리졸버는 생성된 GraphQL 스키마의 기존 입력 유형을 사용합니다.

두 번째 드롭다운 입력에서 단일 입력 객체 또는 동일한 유형의 다중 입력 객체 배열을 선택합니다.

예제

Existing Type 옵션을 사용하여 TaskInsertInput 입력 유형을 지정하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같이 스키마가 생성됩니다:

type Query {
myCustomQuery(input: TaskInsertInput): DefaultPayload
...
}
Custom Type

App Services는 사용자가 정의한 스키마를 기반으로 리졸버에 대한 새로운 입력 유형을 생성합니다. 스키마는 하나 이상의 속성과 생성된 입력 유형에 대한 고유 이름을 정의하는 title 필드를 포함하는 object여야 합니다.

사용자 지정 입력 유형에 대한 사용자 지정 리졸버 구성입니다.

예제

입력 유형이 MyCustomQueryInputCustom Type 옵션을 사용하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

input MyCustomQueryInput {
someArgument: String;
}
type Query {
myCustomQuery(input: MyCustomQueryInput): DefaultPayload
...
}
5

모든 GraphQL 리졸버는 스키마의 특정 유형을 준수하는 페이로드를 반환해야 합니다. 사용자 정의 리졸버의 경우, 기존에 생성된 문서 유형을 사용하거나, 리졸버를 위해 특별히 새로운 사용자 정의 페이로드 유형을 정의하거나, 기본 페이로드를 사용할 수 있습니다. App Services는 사용자 지정 리졸버에서 생성한 GraphQL 스키마 정의에 지정된 페이로드 유형을 포함합니다.

Payload Type 드롭다운에서 다음 옵션 중 하나를 선택합니다:

옵션
설명
DefaultPayload

리졸버는 다음 서명이 있는 자동으로 생성된 DefaultPayload 유형을 반환합니다.

type DefaultPayload {
status: String!
}

status 필드는 리졸버 함수의 반환 값에 관계없이 항상 "complete"(으)로 해결됩니다.

{
status: "complete"
}

예제

DefaultPayload 옵션을 사용하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

type Query {
myCustomQuery: DefaultPayload
...
}
Scalar

리졸버는 생성된 GraphQL 스키마의 기존 스칼라 유형을 사용합니다.

두 번째 드롭다운 입력에서 단일 스칼라 또는 동일한 유형의 다중 스칼라 배열을 선택합니다.

예제

Scalar Type 옵션을 사용하여 DateTime의 페이로드 유형을 지정하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같이 스키마가 생성됩니다:

type Query {
myCustomQuery: DateTime
...
}
Existing Type

리졸버는 생성된 GraphQL 스키마에서 기존 문서 유형을 반환합니다.

두 번째 드롭다운 입력에서 단일 문서 유형 또는 동일한 유형의 다중 문서 배열을 선택합니다.

예제

Existing Type 옵션을 사용하여 TaskInsertInput 입력 유형을 지정하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같이 스키마가 생성됩니다:

Existing Type 옵션을 사용하여 [Task]의 페이로드 유형을 지정하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같이 스키마가 생성됩니다:

type Query {
myCustomQuery: [Task]
...
}
Custom Type

App Services는 사용자가 정의한 스키마를 기반으로 리졸버를 위해 특별히 새로운 페이로드 유형을 생성합니다. 스키마는 하나 이상의 속성과 생성된 입력 유형에 대한 고유 이름을 정의하는 title 필드를 포함하는 object여야 합니다.

새로운 사용자 지정 페이로드 유형을 정의하는 사용자 지정 리졸버 구성입니다.

예제

Custom Type 옵션과 MyCustomQueryPayload라고 명명된 페이로드 유형을 사용하는 myCustomQuery 사용자 지정 리졸버에는 다음과 같은 스키마가 생성됩니다:

input MyCustomQueryPayload {
someValue: String;
}
type Query {
myCustomQuery: MyCustomQueryPayload
...
}
6

사용자가 사용자 지정 리졸버를 호출하면 App Services는 리졸버 함수를 실행하고 결과를 반환합니다. 이는 리졸버의 Payload Type을 준수해야 합니다.

App Services는 해당하는 경우 작업의 모든 입력 데이터를 함수에 전달합니다. 리졸버가 문서 유형의 계산된 속성인 경우 App Services는 리졸버가 호출된 특정 문서를 함수에 전달합니다.

사용자 지정 리졸버 함수에는 입력을 허용하는지 여부에 따라 두 가지 중 하나의 서명이 포함됩니다:

리졸버 함수를 정의하려면 Function 드롭다운을 클릭하고 기존 함수를 선택하거나 새 함수를 생성합니다.

7

리졸버를 구성한 후 Save를 클릭하고 애플리케이션을 배포합니다. 배포가 완료되면 GraphQL API를 통해 사용자 정의 리졸버를 호출할 수 있습니다.

영업 팀이 지정된 기간 동안 다양한 통계 및 기타 성과 메트릭을 표시하는 데 사용하는 가상의 대시보드를 고려합니다. 대시보드는 이 섹션의 사용자 지정 리졸버을 사용하여 일부 특정 사용 사례를 처리합니다.

리졸버는 모두 다음 스키마를 가진 Sale 문서를 참조합니다.

영업팀의 가상 대시보드는 특정 월에 대해 집계된 영업 데이터를 반환하는 사용자 지정 쿼리 리졸버를 사용합니다.

App Services는 리졸버의 사용자 지정 입력 및 페이로드 유형에 대한 스키마 정의를 생성하고 해당 리졸버를 상위 유형인 루트 수준 Query에 추가합니다:

type Query {
averageSaleForMonth(input: AverageSaleForMonthInput): AverageSaleForMonthPayload
}
input AverageSalesForMonthInput {
month: String!;
year: String!;
}
type AverageSaleForMonthPayload {
month: String!;
year: String!;
averageSale: Float!;
}

리졸버는 다음 구성을 사용합니다:

옵션
설명
Parent Type
Query
GraphQL Field Name
averageSaleForMonth
Input Type

사용자 지정 유형: AverageSaleForMonthInput

Payload Type

사용자 지정 유형: AverageSaleForMonthPayload

Function
exports = async function averageSaleForMonth({ month, year }) {
const cluster = context.services.get("mongodb-atlas");
const sales = cluster.db("corp").collection("sales");
const averageSalePayload = await sales
.aggregate([
{ $match: { month: month, year: year } },
{
$group: {
_id: { month: "$month", year: "$year" },
averageSale: { $avg: "$saleTotal" },
}
},
{
$project: {
month: "$_id.month",
year: "$_id.year",
averageSale: 1
}
}
])
.next();
return averageSalePayload;
};

이 사용자 지정 쿼리를 호출하려면 다음 연산과 변수를 사용할 수 있습니다:

query GetAverageSaleForMonth($averageSaleInput: AverageSaleForMonthInput!) {
averageSaleForMonth(input: $averageSaleInput) {
month
year
averageSale
}
}
{
"variables": {
"averageSaleInput": { month: "March", year: "2020" }
}
}

영업팀의 가상 대시보드에서는 _id로 식별되는 특정 Sale 문서에 문자열 메모를 추가하는 사용자 지정 변형 리졸버를 사용합니다.

App Services는 리졸버의 사용자 지정 입력 유형에 대한 스키마 정의를 생성하고 해당 리졸버를 상위 유형인 루트 수준 Mutation에 추가합니다:

type Mutation {
addNoteToSale(input: AddNoteToSaleInput): Sale
}
input AddNoteToSaleInput {
sale_id: ObjectId!;
note: String!;
}

리졸버는 다음 구성을 사용합니다:

옵션
설명
Parent Type
Mutation
GraphQL Field Name
addNoteToSale
Input Type

사용자 지정 유형: AddNoteToSaleInput

Payload Type

기존 유형: Sale

Function
exports = async function addNoteToSale({ sale_id, note }) {
const cluster = context.services.get("mongodb-atlas");
const sales = cluster.db("corp").collection("sales");
const sale = await sales.findOneAndUpdate(
{ _id: sale_id },
{ $push: { notes: note } },
{ returnNewDocument: true }
);
return sale;
}

이 사용자 지정 쿼리를 호출하려면 다음 연산과 변수를 사용할 수 있습니다:

mutation AddNoteToSale($addNoteToSaleInput: AddNoteToSaleInput) {
addNoteToSale(input: $addNoteToSaleInput) {
_id
customer_id
month
year
saleTotal
notes
}
}
{
"variables": {
"addNoteToSaleInput": {
"sale_id": "5f3c2779796615b661fcdc25",
"note": "This was such a great sale!"
}
}
}

영업팀의 가상 대시보드에서는 각 Sale 문서에 새로운 계산된 속성을 추가하는 사용자 지정 리졸버를 사용합니다. 작업에서 지정된 Sale에 대한 계산된 필드를 요청하면 리졸버는 외부 시스템을 쿼리하고 관련 고객이 제출한 지원 사례를 반환합니다.

App Services는 리졸버의 사용자 지정 페이로드 유형에 대한 스키마 정의를 생성하고 해당 상위 유형인 Sale에 리졸버를 추가합니다.

type Sale {
_id: ObjectId!
customer_id: String!
year: String!
month: String!
saleTotal: Float!
notes: [String]
customerSupportCases: [CustomerSupportCase]
}
type CustomerSupportCase {
caseId: String!
description: String!
}

리졸버는 다음 구성을 사용합니다:

옵션
설명
Parent Type
Sale
GraphQL Field Name
customerSupportCases
Input Type
none
Payload Type

사용자 지정 유형: [CustomerSupportCase]

Function
exports = async function customerSupportCases(sale) {
// Return a list of objects from some external system
const cases = await fetchCustomerSupportCases({
customerId: sale.customer_id
});
return cases;
};

이 사용자 지정 계산된 속성을 사용하려면 다음 작업을 실행하면 됩니다:

query GetSalesWithSupportCases {
sales {
_id
customer_id
year
month
saleTotal
notes
customerSupportCases {
caseId
description
}
}
}
← GraphQL 유형, 해석기 및 연산자