쿼리 함수
쿼리 함수Field To Input

Field To Input

Included in the “Power Extensions” bundle

필드의 값을 가져와 가공한 후, 동일한 오퍼레이션 내에서 다른 필드나 디렉티브의 입력값으로 전달합니다.

field 필드의 값을 $__field를 사용하여 다른 필드의 입력값으로 전달하고, field @passOnwards(as: "variableName")를 사용하여 디렉티브의 입력값으로 전달합니다.

$__field

필드의 값을 다른 필드의 입력값으로 전달합니다. 필드 값을 참조하기 위한 구문은 $(GraphQL에서 변수를 나타내는 기호)에 이어 __와 필드 별칭 또는 이름을 작성합니다.

예를 들어, excerpt 필드의 값은 $__excerpt로 참조되고, postTitle: title$__postTitle로 참조됩니다.

두 번째 필드의 응답은 그 자체로 다른 필드의 입력값으로 사용할 수 있습니다.

{
  posts {
    excerpt
 
    # Referencing previous field with name "excerpt"
    isEmptyExcerpt: _isEmpty(value: $__excerpt)
 
    # Referencing previous field with alias "isEmptyExcerpt"
    isNotEmptyExcerpt: _not(value: $__isEmptyExcerpt)
  }
}

응답은 다음과 같습니다.

{
  "data": {
    "posts": [
      {
        "excerpt": "Some post excerpt",
        "isEmptyExcerpt": false,
        "isNotEmptyExcerpt": true
      },
      {
        "excerpt": "",
        "isEmptyExcerpt": true,
        "isNotEmptyExcerpt": false
      }
    ]
  }
}
# This will fail because the reference to the field must appear after the field, not before
{
  posts {
    isEmptyExcerpt: _isEmpty(value: $__excerpt)
    excerpt
  }
}
 
# This will fail because the reference must be done within the same node
{
  posts {
    excerpt
  }
  isEmptyExcerpt: _isEmpty(value: $__excerpt)
}

필드는 디렉티브 인수에서도 참조할 수 없습니다(해당 경우에는 @passOnwards를 사용하세요).

# This will fail because the reference can be only used as input to a field, not to a directive
{
  posts {
    hasComments
    title @include(if: $__hasComments)
  }
}

@passOnwards

디렉티브 @passOnwards는 필드의 해결된 값을 다이나믹 변수를 통해 이후 디렉티브에서 사용할 수 있도록 합니다.

아래 쿼리에서 notHasComments 필드는 hasComments 필드의 값을 가져와 반대 값을 계산하여 구성됩니다. 동작 방식은 다음과 같습니다.

  • @passOnwards를 사용하여 필드의 값을 사용 가능하게 만듭니다. 이후 필드의 값은 후속 디렉티브에 입력값으로 전달될 수 있습니다
  • @applyField는 입력값(다이나믹 변수 $postHasComments로 내보낸 값)을 받아 글로벌 필드 not을 적용하고 결과를 필드에 저장합니다
{
  posts {
    id
    hasComments
    notHasComments: hasComments
      @passOnwards(as: "postHasComments")
      @applyField(
        name: "_not"
        arguments: {
          value: $postHasComments
        },
        setResultInResponse: true
      )
  }
}

이렇게 하면 다음이 생성됩니다.

{
  "data": {
    "posts": [
      {
        "id": 1724,
        "hasComments": true,
        "notHasComments": false
      },
      {
        "id": 358,
        "hasComments": false,
        "notHasComments": true
      },
      {
        "id": 555,
        "hasComments": false,
        "notHasComments": true
      }
    ]
  }
}

property 인수에 별칭 또는 필드 이름을 전달하여 객체 내의 해결된 필드 값을 가져올 수도 있습니다.

예를 들어, 이 쿼리에서는 필드 이름 id 또는 별칭 second로 해결된 값에 접근하여, 그 값을 다이나믹 변수로 내보내 후속 쿼리에서 출력합니다.

query One {
  id
  second: _echo(value: 2)
    @passOnwards(
      property: "id",
      as: "resolvedFirstValue"
    )
    @exportFrom(
      scopedDynamicVariable: $resolvedFirstValue,
      as: "firstValue"
    )
  third: _echo(value: 3)
    @passOnwards(
      property: "second",
      as: "resolvedSecondValue"
    )
    @exportFrom(
      scopedDynamicVariable: $resolvedSecondValue,
      as: "secondValue"
    )
}
 
query Two @depends(on: "One") {
  firstValue: _echo(value: $firstValue)
  secondValue: _echo(value: $secondValue)
}

이렇게 하면 다음이 생성됩니다.

{
  "data": {
    "id": "root",
    "second": 2,
    "third": 3,
    "firstValue": "root",
    "secondValue": 2
  }
}

사용 예시

포스트의 발췌문이 비어 있는 경우 대신 제목을 사용합니다.

{
  posts {
    title
    originalExcerpt: excerpt
    isEmptyExcerpt: _isEmpty(value: $__originalExcerpt)
    excerpt: _if(condition: $__isEmptyExcerpt, then: $__title, else: $__originalExcerpt)
  }
}

외부 REST 엔드포인트에서 데이터를 가져와 필요에 맞게 가공합니다.

{
  externalData: _sendJSONObjectItemHTTPRequest(input: { url: "https://example.com/rest/some-external-endpoint"} )
  userName: _objectProperty(object: $__externalData, by: { path: "data.user.name" })
  userLastName: _objectProperty(object: $__externalData, by: { path: "data.user.surname" })
}

이렇게 하면 다음이 생성됩니다.

{
  "data": {
    "externalData": {
      "data": {
        "user": {
          "id": 1,
          "name": "Leo",
          "surname": "Loso"
        }
      }
    },
    "userName": "Leo",
    "userLastName": "Loso"
  }
}

externalData@remove 디렉티브를 사용하면 응답에서 외부 엔드포인트 소스 데이터를 출력하지 않을 수도 있습니다.

{
  externalData: _sendJSONObjectItemHTTPRequest(input: { url: "https://example.com/rest/some-external-endpoint" } ) @remove
  userName: _objectProperty(object: $__externalData, by: { path: "data.user.name" })
  userLastName: _objectProperty(object: $__externalData, by: { path: "data.user.surname" })
}

이렇게 하면 다음과 같이 출력됩니다.

{
  "data": {
    "userName": "Leo",
    "userLastName": "Loso"
  }
}

각 사용자의 이메일 주소를 검색 조건으로 하여, 해당 사용자를 언급하는 포스트를 가져옵니다.

{
  users {
    email
    posts(filter: { search: $__email }) {
      id
      title
    }
  }
}

optionValue 필드를 통해 tofrom 이메일 주소를 정의하여 뉴스레터를 발송합니다.

mutation {
  fromEmail: optionValue(name: "admin_email")
  toEmail: optionValue(name: "subscribers_email_list_recipient_address")
  _sendEmail(
    from: {
      email: $__fromEmail
    }
    to: $__toEmail
    subject: "Weekly summary"
    messageAs: {
      html: "..."
    }
  )
}

필드 값을 기반으로 조건부 오퍼레이션을 실행합니다. 이 쿼리에서는 "특별 사용자" 배열에 포함된 "Leo""Peter"의 이름이 대문자로 변환되지만, "Martin"은 그렇지 않습니다.

query {
  users {
    name
      @passOnwards(as: "userName")
      @applyField(
        name: "_inArray"
        arguments: {
          value: $userName
          array: ["Leo", "John", "Peter"]
        }
        passOnwardsAs: "isSpecialUser"
      )
      @if(
        condition: $isSpecialUser
      )
        @strUpperCase
  }
}

...결과는 다음과 같습니다.

{
  "data": {
    "users": [
      {
        "name": "LEO"
      },
      {
        "name": "Martin"
      },
      {
        "name": "PETER"
      }
    ]
  }
}