고급 API 옵션 설정

이 페이지에서는 유형 공급자에 입력 매핑 및 가상 속성과 같은 고급 구성 옵션을 설정하는 방법을 설명합니다. 유형에 대한 자세한 내용은 유형 개요를 참조하세요. 유형 공급자에 대한 자세한 내용은 Deployment Manager와 통합하는 방법에 대한 1페이지 가이드를 참조하세요.

Deployment Manager에서 정의된 API 요구사항을 충족하지 않는 API를 통합하려는 경우 입력 매핑 및 가상 속성을 사용하여 이러한 불일치를 해결할 수 있습니다. 입력 매핑은 모호한 API 매개변수를 명시적으로 매핑하고, 가상 속성은 기본 API에 존재하지 않는 임의적인 속성을 노출하여 입력을 단순화하고 복잡한 API가 사용자에게 표시되지 않도록 합니다.

고급 구성 옵션을 구현하기 위해서는 유형 공급자를 만들 때 사용하는 API를 잘 다룰 수 있어야 합니다. 각 API는 서로 크게 다르기 때문에 이 페이지에서는 일반적인 지침과 예제만 제공하고 특정 API 가이드는 제공하지 않습니다.

시작하기 전에

고급 구성 옵션이 필요한 일반적인 시나리오

서로 다른 값으로 재사용되는 속성 이름

특정 API에서는 동일한 속성 또는 매개변수 이름을 여러 메서드에서 서로 다른 값으로 재사용할 수 있습니다. 예를 들어 API에서 리소스를 만드는 데(POST 요청) 필요한 name 매개변수에 foo/bar 값을 지정하고, 업데이트 요청(PATCH 또는 PUT)에 필요한 같은 name 필드에 foo/bar/baz 값이 필요하도록 지정할 수 있습니다.

API 응답으로부터 유추할 수 있는 속성 값

특정 API 메서드에는 리소스에 GET 요청을 보낼 때 반환되는 서버 생성 값이 필요합니다. 예를 들어 리소스를 변환할 때 업데이트 요청을 수행하기 위해 API에 etag 매개변수가 필요할 수 있습니다. etag 값은 변환 요청이 수행될 때마다 바뀌므로, 리소스 업데이트 요청을 수행하기 전에 리소스에 GET 요청을 보내 현재 etag 매개변수를 가져올 수 있습니다.

입력 매핑을 사용하면 API 리소스에서 etag 필드를 검색할 수 있음을 Deployment Manager에 알릴 수 있습니다. Deployment Manager는 입력 매핑에 지정한 메서드를 사용자가 호출할 때 GET 요청을 자동으로 수행하여 이 값을 가져옵니다.

사용자 입력 단순화

Deployment Manager는 여러 용도로 Deployment Manager를 통해 사용자에게 노출할 수 있는 임의 속성인 가상 속성을 지원합니다. 가상 속성은 기본 API에 존재하지 않는 속성으로 취급되지만 개발자가 필요에 따라 자신의 입력 매핑에 값을 입력할 수 있는 임의 변수입니다. 예를 들어 값을 기본 API로 전송하기 전 base64로 인코딩되어야 하는 API 속성이 있다고 가정해 봅시다. 이 경우에는 사용자에게 값을 base64 인코딩 형식으로 제공하도록 요청하는 대신 사용자에게 일반 텍스트 값을 요청하는 가상 속성을 만들고 입력 매핑에 따라 값을 base64로 인코딩한 후 마지막으로 결과를 기본 API에 제공할 수 있을 것입니다.

고급 옵션 지정

고급 옵션을 지정하려면 유형 공급자 리소스를 만들 때 collectionOverrides 속성을 제공하고 필요에 따라 각 API 컬렉션에 입력 매핑 또는 가상 속성을 정의합니다.

예를 들어 gcloud CLI를 사용할 경우 YAML 파일을 사용하여 고급 옵션을 제공하고 type-providers create 요청에 이 YAML 파일을 제공할 수 있습니다. 샘플 YAML 파일은 다음과 비슷할 수 있습니다.

collectionOverrides:
- collection: /emailAddresses/v1beta/people
  options:
    inputMappings:
    - methodMatch: ^create$
      fieldName: emailAddress.displayName
      value: $.resource.properties.displayName
      location: BODY
    - methodMatch: ^update$
      fieldName: displayName
      value: $.resource.properties.displayName
      location: PATH
    virtualProperties: |
      schema: http://json-schema.org/draft-04/schema#
      type: object
        properties:
          displayName:
            type: string
credential:
  basicAuth:
    user: [USERNAME]
    password: [PASSWORD]

이 구성은 Deployment Manager에 다음을 알려줍니다.

  • create 메서드의 경우 리소스 본문에서 emailAddress.displayName이라는 필드를 찾고 이 필드의 값을 Deployment Manager 구성의 displayName 속성에 대한 사용자 입력으로 설정합니다. 예를 들어 사용자가 다음과 같이 구성을 설정한다고 가정합니다.

     resources:
     - name: example
       type: myproject/emailAddress:/emailAddresses/v1beta/people
       properties:
       - displayName: John Doe
         ...
    

    그러면 Deployment Manager가 emailAddress.displayName의 값을 John Doe로 설정합니다.

  • update 메서드의 경우 필드는 리소스 본문 대신 리소스 경로에 있지만 동일한 입력 매핑이 적용됩니다.

입력 매핑 지정

입력 매핑은 특정 API 필드에 대해 정보를 매핑하거나 삽입할 수 있게 함으로써 Deployment Manager가 기본 API와 더 효율적으로 상호작용할 수 있게 하고, 사용자가 복잡한 API 동작을 이해해야 하는 부담을 줄여줍니다.

입력 매핑을 사용하면 사용자가 API와 상호작용 방법을 단순화할 수 있습니다. 예를 들어 입력 매핑을 사용하여 지문, ID 또는 ETag와 같은 서버에서 생성된 값을 자동으로 가져올 수 있습니다. 이렇게 하면 사용자가 업데이트를 수행하려 할 때마다 리소스에 개별적으로 get 요청을 수행해야 하는 수고가 줄어듭니다.

마찬가지로, 입력 매핑을 사용하여 동일한 API 필드에 서로 다른 메서드의 서로 다른 값이 포함되는 모호하거나 혼란스러운 상황을 처리할 수 있습니다. 예를 들어 리소스 생성 요청 시 사용자가 지정할 수 있는 name 속성이 필요할 수 있지만 동일한 API에서는 update 메서드에 다른 형식의 name 속성이 필요할 수 있습니다. 입력 매핑을 사용하면 각 API 메서드마다 어떤 값이 적합한지를 Deployment Manager에 알려줄 수 있습니다.

유형 공급자에 입력 매핑을 지정하려면 options.inputMappings 속성을 제공합니다. 전체 API에 적용되는 입력 매핑을 정의하거나 각 컬렉션마다 입력 매핑을 명시적으로 제공할 수 있습니다.

# Input mappings for the entire API
"options": {
  "inputMappings": [
      {
          "fieldName": "[NAME]",
          "location":  "[PATH | BODY | QUERY | HEADER]",
          "methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
          "value": "[VALUE_TO_INJECT]"
      },
      {
          "fieldName": "[NAME]",
          "location":  "[PATH | BODY | QUERY | HEADER]",
          "methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
          "value": "[VALUE_TO_INJECT]"
      }
   ]
},
# Input mappings for specific collections
"collectionOverrides": [
    {
        "collection": "[SPECIFIC_COLLECTION]",
        "options": {
            "inputMappings": [
                {
                    "fieldName": "[NAME]",
                    "location": "[PATH | BODY | QUERY | HEADER]",
                    "methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
                    "value": "[VALUE_TO_INJECT]"
                },
                {
                    "fieldName": "[NAME]",
                    "location": "[PATH | BODY]",
                    "methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
                    "value": "[VALUE_TO_INJECT]"
                },
                ...[additional fields if necessary]...
            ]
        }
    }
]

이 구문에서 중요한 각 부분에 대해서는 아래에서 설명합니다.

컬렉션

[SPECIFIC_COLLECTION]은 이 입력 매핑이 적용되는 API 컬렉션입니다. 예를 들어 IAM Service Accounts API와 같은 Google Discovery 문서에 입력 매핑을 제공한 경우 관련 컬렉션은 projects.serviceAccountsprojects.serviceAccountKeys입니다.

OpenAPI 사양을 사용하는 API의 경우 컬렉션 경로는 /example-collection/{name}일 수 있습니다. OpenAPI GitHub 저장소에서 작동 가능한 OpenAPI 예시를 찾아볼 수 있습니다.

필드 이름

"fieldName"은 입력 매핑을 지정하려는 속성이거나 API 속성입니다. 예를 들면 "fieldName": "fingerprint", "fieldName": "etag" 등입니다.

위치

API 속성은 URL 경로에 매개변수로 또는 요청이나 응답 본문의 일부로 표시될 수 있습니다. URL PATH 또는 요청 BODY와 같이, 이 매핑이 적용되는 위치를 지정합니다. 지원되는 값은 다음과 같습니다.

  • PATH
  • BODY
  • QUERY
  • HEADER

메서드 일치

이 입력 매핑이 적용되는 메소드를 지정합니다. 정규 표현식을 사용하여 여러 메소드를 지정합니다. 예를 들면 다음과 같습니다.

"methodMatch":"^create$"

OpenAPI 사양의 경우 다음을 수행할 수 있습니다.

"methodMatch: ^(put|get|delete|post)$"

Deployment Manager가 이 필드에 대해 삽입해야 하는 값을 지정합니다. 이 필드는 JSONPath 표기법을 사용합니다. 예를 들어 이 입력 매핑은 name 필드의 경우 Deployment Manager가 사용자가 제공한 값을 사용하고 projects/$.project/topics/$resource.properties.topic 형식으로 삽입하도록 지정합니다.

"inputMappings":[
{
  "fieldName":"name",
  "location":"PATH",
  "methodMatch":"^post$",
  "value":"concat(\"projects/\", $.project, \"/topics/\", $.resource.properties.topic)"
}...
  • $.resource.properties.[VARIABLE]을 사용하는 경우 값을 사용자가 구성에서 설정할 속성으로 설정합니다. 예를 들어 $.resource.properties.topic의 경우 값은 구성에서 topic 속성에 사용자가 제공한 값이 됩니다.

    resources:
    - name: example
      type: example-type-provider:collectionA
      properties:
        topic: history # The value of "history" would be used for the `name` parameter because of the input mapping above
    
  • get 요청 후 리소스 자체를 참조하려면 $.resource.self.[VARIABLE]을 사용합니다. 예를 들어 업데이트 요청의 경우 최신 지문을 가져오려 했으면 이 구문을 사용하여 Deployment Manager에게 get을 수행하여 값을 가져오라고 지시할 수 있습니다.

    {
      'fieldName': 'fingerprint',
      'location': 'BODY',
      'methodMatch': '^(put)$',
      # self represents the resource by doing a GET on it.
      # This mappings gets latest fingerprint on the request.
      # Final PUT Body will be
      # {
      #   "name": "my-resource-name",
      #   "fingerprint": "<server generated fingerprint>"
      # }
      'value': '$.resource.self.fingerprint'
    }
    

가상 속성 사용

가상 속성은 Deployment Manager를 통해 사용자에게 노출할 수 있는 임의 속성입니다. 이러한 속성은 기본 API에 포함되지 않지만, 정보를 전달하거나 사용자에게 API의 불일치성을 숨기기 위해 사용할 수 있는 임의 변수입니다. 가상 속성은 입력 매핑에서도 참조할 수 있습니다.

가상 속성은 JSON 4 스키마를 따릅니다. 특정 컬렉션에서 options의 일부로 가상 속성을 제공합니다.

"collection": "[SPECIFIC_COLLECTION]",
  "options": {
   "virtualProperties": "schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n  [PROPERTY]:\n    type: [DATA_TYPE]\n  [ANOTHER_PROPERTY]:\n    type: [ANOTHER_DATA_TYPE]n"
   "inputMappings": [
    ...
   ]
  }

YAML 정의 파일에서는 다음과 같이 표시됩니다.

- collection: projects.serviceAccounts
  options:
    virtualProperties: |
      schema: http://json-schema.org/draft-04/schema#
      type: object
      properties:
        a-property:
          type : string
        b-property:
          type : string
      required:
      - a-property
      - b-property
    inputMappings:
    ...

예를 들어 이메일 주소를 생성하는 가짜 API가 있다고 가정합니다. 그리고 이 API에는 emailAddress.displayName 속성을 받아들여 이메일을 만드는 메서드가 있다고 가정해 봅니다. 사용자가 이메일 주소 만들기 요청을 수행하면 다음과 같이 요청이 제공됩니다.

POST https://example.com/emailAddresses/v1beta/people/

{
  "emailAddress": {
    "displayName": "john"
  }
}

이제 API가 이메일 주소 업데이트 방법을 노출합니다. 하지만 이메일을 업데이트하는 메서드에는 email.displayName 속성이 아닌 displayName 속성이 필요하다고 가정해 봅니다.

POST https://example.com/emailAddresses/v1beta/people/john

{
  "displayName": "josh"
}

사용자가 이 유형 공급자를 사용할 때 이 값을 제공하도록 하려면 어떻게 해야 할까요? 이를 위해서는 작업에 따라 속성을 다르게 지정하도록 요청할 수 있을 것입니다.

# Creating an email
resources:
- name: example-config
  type: projects/test-project:emailAddresses
  properties:
    emailAddress:
      displayName: john


# Updating an email
resources:
- name: example-config
  type: projects/test-project:emailAddresses
  properties:
    displayName: john

또는 작업에 관계없이 동일한 값을 사용하는 가상 속성을 만든 후 입력 매핑을 사용하여 가상 속성을 적절한 API 매개변수에 매핑할 수 있습니다. 이 예시에서는 displayName이라는 가상 속성을 정의했다고 가정합니다. 입력 매핑은 다음과 같을 수 있습니다.

{
    "collectionOverrides":[
      {
        "collection":"emailAddresses",
        "options":{
          "inputMappings":[
            {
              "fieldName":"emailAddress.displayName",
              "location":"BODY",
              "methodMatch":"^create$",
              "value":"$.resource.properties.displayName"
            },
            {
              "fieldName":"displayName",
              "location":"BODY",
              "methodMatch":"^update$",
              "value":"$.resource.properties.displayName"
            }
          ],
          "virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n  displayName:\n    type: string\nrequired:\n- displayName\n"
        }
      }
    ],
    "descriptorUrl":"https://example.com/emailAddresses/v1beta/",
    "options":{
      "nameProperty":""
    }
}

특히 가상 속성은 여기에 정의됩니다.

"virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n  displayName:\n    type: string\nrequired:\n- displayName\n"

사람이 읽을 수 있는 형식은 다음과 같습니다.

"virtualProperties":
  "schema: http://json-schema.org/draft-04/schema#\n
   type: object\n
   properties:\n
     displayName:\n
     - type: string\n
   required:\n
   - displayName\n"

이제 사용자는 업데이트 및 생성 요청 모두의 최상위 수준 속성으로 displayName을 지정할 수 있으며, Deployment Manager는 값을 올바르게 매핑하는 방법을 알게 됩니다.

# Creating an email
resources:
- name: example-config
  type: projects/test-project:emailAddresses
  properties:
    displayName: john


# Updating an email
resources:
- name: example-config
  type: projects/test-project:emailAddresses
  properties:
    displayName: john

다음 단계