Erweiterte API-Optionen festlegen

Auf dieser Seite wird gezeigt, wie Sie erweiterte Konfigurationsoptionen wie Eingabezuordnungen und virtuelle Attribute für Typanbieter einrichten. Weitere Informationen über Typen finden Sie unter Typenübersicht. Weitere Informationen über Typanbieter finden Sie in der Kurzanleitung zur Integration in Deployment Manager.

Wenn Sie versuchen, eine API zu integrieren, die die von Deployment Manager definierten API-Anforderungen nicht erfüllt, können Sie Eingabezuordnungen und virtuelle Eigenschaften verwenden, um diese Inkonsistenzen zu lösen. Mit Eingabezuordnungen stellen Sie ausdrückliche Zuordnungen zu API-Parametern her, wodurch Sie Unklarheiten beseitigen. Mit virtuellen Attributen zeigen Sie beliebige Attribute an, die nicht in den zugrunde liegenden APIs. vorhanden sind. Auf diese Weise können Sie die Eingabe vereinfachen und komplexe API-Zusammenhänge vor Ihren Nutzern verbergen.

Die Implementierung erweiterter Konfigurationsoptionen erfordert genaue Kenntnisse der API, für die Sie den Typanbieter erstellen. Da jede API stark von anderen APIs abweichen kann, enthält diese Seite allgemeine Anleitungen und Beispiele, bietet jedoch keine Anleitungen für spezifische APIs.

Hinweise

Anforderungen für erweiterte Konfigurationsoptionen

Attributnamen mit anderen Werten wiederverwenden

In bestimmten APIs kann der gleiche Attribut- oder Parametername in verschiedenen Methoden, aber mit unterschiedlichen Werten wiederverwendet werden. Beispiel: Eine API verwendet den Parameter name zum Erstellen einer Ressource mit einer POST-Anfrage. Der Wert des Parameters könnte foo/bar lauten. Gleichzeitig könnte dasselbe name-Feld für eine Aktualisierungsanfrage mit PATCH oder PUT den Wert foo/bar/baz erfordern.

Attributwerte aus der API-Antwort ableiten

Bestimmte API-Methoden erfordern einen vom Server generierten Wert, der zurückgegeben wird, wenn Sie eine GET-Anfrage an die Ressource stellen. So benötigt eine API z. B. möglicherweise einen etag-Parameter, um beim Mutieren einer Ressource Aktualisierungsanfragen vorzunehmen. Der Wert etag ändert sich nach jeder Mutationsanfrage. Wenn Sie eine GET-Anfrage an die Ressource ausführen, bevor Sie die Anfrage zum Aktualisieren der Ressource stellen, wird daher der aktuelle etag-Parameter abgerufen.

Mit Eingabezuordnungen legen Sie fest, dass Deployment Manager das Feld etag von der API-Ressource abrufen kann. Deployment Manager führt automatisch eine GET-Anfrage aus, um diesen Wert zu erhalten, wenn ein Nutzer die Methode aufruft, die Sie in den Eingabezuordnungen angegeben haben.

Nutzereingabe vereinfachen

Deployment Manager unterstützt virtuelle Attribute, die beliebige Attribute sind und die Sie Ihren Nutzern über Deployment Manager für verschiedene Zwecke anzeigen können. Behandeln Sie virtuelle Attribute wie Attribute, die nicht in der zugrunde liegenden API vorhanden sind, aber wie beliebige Variablen funktionieren, deren Werte Sie bei Bedarf in Ihre Eingabezuordnungen einfließen lassen können. Nehmen wir zum Beispiel an, ein API-Attribut muss Base64-codiert werden, bevor der Wert an die zugrunde liegende API gesendet wird. Anstatt Ihre Nutzer aufzufordern, einen Base64-codierten Wert bereitzustellen, können Sie ein virtuelles Attribut erstellen, das den Nutzer zur Eingabe von Klartext auffordert. Die Base64-Codierung des Wertes wird dann über eine Eingabezuordnung gelöst. Anschließend wird der korrekt codierte Wert an die zugrunde liegende API übergeben.

Erweiterte Optionen festlegen

Wenn Sie erweiterte Optionen festlegen möchten, müssen Sie beim Erstellen einer Typanbieter-Ressource das Attribut collectionOverrides bereitstellen. Definieren Sie dann für jede API-Sammlung je nach Bedarf Eingabezuordnungen oder virtuelle Attribute.

Mit der gcloud CLI können Sie beispielsweise erweiterte Optionen mithilfe einer YAML-Datei bereitstellen und die YAML-Datei mit Ihrer type-providers create-Anfrage bereitstellen. Eine Beispiel-YAML-Datei könnte so aussehen:

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]

Diese Konfiguration legt für Deployment Manager Folgendes fest:

  • Die Methode create finden Sie im Ressourcentext im Feld mit dem Namen emailAddress.displayName. Setzen Sie in der Konfiguration von Deployment Manager den Wert des Felds auf das Attribut displayName, das der Nutzer eingegeben hat. Beispiel für eine Nutzerkonfiguration:

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

    Deployment Manager setzt den Wert für emailAddress.displayName auf "John Doe".

  • Für die Methode update befindet sich das Feld im Ressourcenpfad und nicht im Ressourcentext. Dennoch wird die gleiche Eingabezuordnung angewendet.

Eingabezuordnungen festlegen

Mithilfe einer Eingabezuordnung können Sie bestimmten API-Feldern Informationen zuordnen oder hinzufügen, sodass Deployment Manager reibungslos mit der zugrunde liegenden API interagieren kann. Auf diese Weise werden Ihre Nutzer entlastet und müssen das Verhalten der API nicht im Detail verstehen.

Eingabezuordnungen können Sie verwenden, um die Interaktion von Nutzern mit der API zu vereinfachen. So können Sie mithilfe von Eingabezuordnungen beispielsweise automatisch servergenerierte Werte abrufen, z. B. Fingerabdrücke, IDs oder Etags. Dies erspart Nutzern die Mühe, jedes Mal eine get-Anfrage an die Ressource zu stellen, wenn eine Aktualisierung durchgeführt werden soll.

In ähnlicher Weise können Sie Eingabezuordnungen verwenden, um mehrdeutige oder verwirrende Situationen zu handhaben, in denen das gleiche API-Feld unterschiedliche Werte für verschiedene Methoden verwendet. Beispiel: Für eine Anfrage zum Erstellen einer Ressource ist möglicherweise ein name-Attribut erforderlich, das der Nutzer angeben kann. Dieselbe API kann allerdings ein name-Attribut in einem anderen Format für update-Methoden benötigen. Sie können Eingabezuordnungen verwenden, um Deployment Manager mitzuteilen, welcher Wert für die jeweilige API-Methode erforderlich ist.

Eingabezuordnungen für einen Typanbieter legen Sie mit dem Attribut options.inputMappings fest. Sie können Eingabezuordnungen definieren, die für die gesamte API gelten, oder für jede Sammlung explizite Eingabezuordnungen bereitstellen:

# 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]...
            ]
        }
    }
]

Jeder wichtige Teil dieser Syntax wird nachstehend beschrieben.

Sammlung

[SPECIFIC_COLLECTION] ist die API-Sammlung, für die diese Eingabezuordnung gilt. Wenn Sie beispielsweise Eingabezuordnungen für ein Google Discovery-Dokument wie die IAM Service Accounts API bereitstellen, sind projects.serviceAccounts und projects.serviceAccountKeys die dafür maßgeblichen Sammlungen.

Für eine API, die eine OpenAPI-Spezifikation verwendet, könnte der Sammlungspfad /example-collection/{name} lauten. Im OpenAPI GitHub-Repository steht für Sie ein OpenAPI-Beispiel zum Ausprobieren bereit.

Feldname

"fieldName" ist das API-Attribut, für das Sie die Eingabezuordnung angeben möchten. Zum Beispiel "fieldName": "fingerprint", "fieldName": "etag" usw.

Standort

API-Attribute können entweder als Parameter im URL-Pfad oder als Teil des Anfrage- oder Antworttextes angezeigt werden. Geben Sie an, wo diese Eingabezuordnung gelten soll, z. B. den Speicherort PATH einer URL oder den BODY-Teil einer Anfrage. Unterstützte Werte sind:

  • PATH
  • BODY
  • QUERY
  • HEADER

Methodenentsprechungen

Geben Sie an, auf welche Methoden diese Eingabezuordnungen angewendet werden. Verwenden Sie reguläre Ausdrücke, um mehrere Methoden anzugeben. Beispiel:

"methodMatch":"^create$"

Für OpenAPI-Spezifikationen geben Sie Folgendes ein:

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

Wert

Geben Sie den Wert an, den Deployment Manager für dieses Feld einfügen soll. Dieses Feld verwendet die JSONPath-Notation. Diese Eingabezuordnung besagt zum Beispiel, dass Deployment Manager für das Feld name den vom Nutzer bereitgestellten Wert verwenden und im Format projects/$.project/topics/$resource.properties.topic einfügen soll:

"inputMappings":[
{
  "fieldName":"name",
  "location":"PATH",
  "methodMatch":"^post$",
  "value":"concat(\"projects/\", $.project, \"/topics/\", $.resource.properties.topic)"
}...
  • Wenn Sie $.resource.properties.[VARIABLE] verwenden, legen Sie den Wert für ein Attribut fest, das ein Nutzer in seiner Konfiguration festlegt. So wird beispielsweise für $.resource.properties.topic der vom Nutzer für das Attribut topic in der Konfiguration angegebene Wert verwendet:

    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
    
  • Um nach einer get-Anfrage auf die Ressource selbst zu verweisen, verwenden Sie $.resource.self.[VARIABLE]. Wenn Sie beispielsweise bei Aktualisierungsanforderungen den neuesten Fingerabdruck abrufen möchten, können Sie mithilfe dieser Syntax festlegen, dass Deployment Manager ein get ausführt und den Wert abruft:

    {
      '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'
    }
    

Virtuelle Attribute verwenden

Virtuelle Attribute sind beliebige Attribute, die Sie für Ihre Nutzer über Deployment Manager anzeigen können. Diese Attribute sind nicht Teil der zugrunde liegenden API, sondern beliebige Variablen, die sich zur Übergabe von Informationen oder zum Verbergen von Inkonsistenzen der API vor Ihren Nutzern verwenden lassen. Sie können auch in Ihren Eingabezuordnungen auf virtuelle Attribute referenzieren.

Virtuelle Attribute folgen dem JSON 4-Schema. Stellen Sie virtuelle Attribute für eine bestimmte Sammlung als Teil von options bereit:

"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": [
    ...
   ]
  }

In einer YAML-Definitionsdatei würde das so aussehen:

- 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:
    ...

Angenommen, Sie haben eine vorgetäuschte API, die E-Mail-Adressen generiert. Außerdem enthält die API eine Methode zum Erstellen von E-Mails, die das Attribut emailAddress.displayName verwendet. Wenn ein Nutzer eine Anfrage zum Erstellen einer E-Mail-Adresse stellt, könnte diese so aussehen:

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

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

Nehmen wir nun an, die API bietet eine Möglichkeit, die E-Mail-Adresse zu aktualisieren. Die Methode zum Aktualisieren einer E-Mail benötigt aber nur das Attribut displayName und nicht das Attribut email.displayName:

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

{
  "displayName": "josh"
}

Wie soll Ihr Nutzer diesen Wert angeben, wenn er diesen Typanbieter verwendet? Sie könnten ihn bitten, das Attribut je nach Vorgang unterschiedlich anzugeben:

# 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

Alternativ könnten Sie ein virtuelles Attribut erstellen, das unabhängig vom Vorgang den gleichen Wert verwendet und dann die Eingabezuordnung nutzt, um das virtuelle Attribut dem entsprechenden API-Parameter zuzuweisen. In diesem Beispiel wird davon ausgegangen, dass Sie ein virtuelles Attribut mit dem Namen displayName definiert haben. Ihre Eingabezuordnungen könnten dann so aussehen:

{
    "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":""
    }
}

Das virtuelle Attribut wird hier definiert:

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

Im für Menschen lesbaren Format:

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

Jetzt können Ihre Nutzer displayName als übergeordnetes Attribut für die Aktualisierungs- und die Erstellungsanfrage angeben. Deployment Manager weiß damit genau, wie die Werte korrekt zuzuordnen sind.

# 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

Nächste Schritte