Anforderungseinschluss

Anforderungseinschluss ist eine Technik für POSTs und PATCHs, bei der der Aufruf Folgendes umfasst:

  • Eine einzelne übergeordnete Anforderung, die eine Ressource erstellt oder ändert
  • Eine oder mehrere untergeordnete Anforderungen, die mit der übergeordneten Ressource verbundene Ressourcen erstellen oder ändern

Wenn entweder die übergeordnete Anforderung oder eine untergeordnete Anforderung fehlschlägt, schlägt die gesamte Anforderung fehl.

Die übergeordnete Ressource wird oft als Stammressource bezeichnet. Die Stammressource wird im data-Abschnitt der Nutzdaten angegeben. Die zugehörigen Ressourcen werden im included-Abschnitt der Nutzdaten angegeben.

Beispielsweise kann ein Aufrufer mithilfe ein einzelnes POST /accounts verwenden, um ein neues Konto, eine Reihe von AccountContacts für dieses Konto, eine Reihe von AccountLocations für dieses Konto und eine Reihe von Dokumenten für dieses Konto zu erstellen.

Um den Anforderungseinschluss zu verwenden, muss Folgendes zutreffen:

  • Für die Stammressource muss ein POST- oder PATCH-Endpunkt vorhanden sein.
  • Dieser Endpunkt muss über die untergeordnete Ressource als Teil des included-Abschnitts verfügen.
  • Für die untergeordnete Ressource muss auch ein POST- oder PATCH-Endpunkt vorhanden sein.

Die Syntax für den Anforderungseinschluss variiert leicht, je nachdem, ob die Beziehung zwischen der Stammressource und der eingeschlossenen Ressource eine „einfache Übergeordnet/Untergeordnet-Beziehung“ oder eine „benannte Beziehung“ ist.

Syntax für einfache hierarchische Beziehungen

In den meisten Fällen ist die Beziehung zwischen der Stammressource und einer eingeschlossenen Ressource eine einfache hierarchische Beziehung. Beispiele hierfür sind:

  • Eine Aktivität und ihre Notizen
  • Ein Konto und seine AccountLocations

Wenn Sie die Einschließung von Anforderungen für einfache hierarchische Beziehungen verwenden, hat das JSON die folgende Struktur:

{
  "data" : {
    "attributes": {
      ...
    }
  },
  "included": {
    "<resourceType>": [
      {
        "attributes": {
          ...
        },
        "method": "post",
        "uri": "/../this/..."
      }
    ]
  }
}

Abschnitt data

Der Abschnitt data enthält Informationen über die Stammressource, z. B. ihre attributes. (Bei PATCHs kann der Abschnitt data auch einen Prüfsummenwert für die Stammressource enthalten.)

Abschnitt included

Der Abschnitt included besteht aus einem oder mehreren Unterabschnitten eingeschlossener Ressourcen. Jeder Unterabschnitt beginnt mit dem Namen des Ressourcentyps. Anschließend können eine oder mehrere Ressourcen dieses Typs angegeben werden. Für jede Ressource müssen Sie die folgenden Informationen angeben werden:

  • attributes der Ressource
  • method und uri zum Erstellen oder Ändern der Ressource.

Felder method und uri.

Die Anforderungseinbindung umfasst einen einzelnen Aufruf eines einzelnen Endpunkts. Intern verwenden die System-APIs jedoch mehrere Endpunkte, um den Aufruf auszuführen. Für jede eingeschlossene Ressource müssen Sie den für diese Ressource relevanten Vorgang und URI angeben.

Angenommen, Sie schreiben einen Aufruf "POST /activities", um eine Aktivität und eine Notiz für diese Aktivität zu erstellen. Die Notiz ist die eingeschlossene Ressource. Der Abschnitt included würde Code ähnlich dem folgenden enthalten:

"included": {
  "Note": [
    {
      "attributes": {
          ...
      },
      "method": "post",
      "uri": "/common/v1/activities/this/notes"
    }
  ]
}

Damit wird angegeben, dass zum Erstellen der Notiz der Endpunkt POST /common/v1/activities/{activityId}/notes verwendet wird.

Der URI muss mit dem API-Namen beginnen, z. B. "/common/v1".

Der URI muss auch die ID der Stammressource angeben. Wenn die Stammressource und die eingeschlossenen Ressourcen gleichzeitig erstellt werden, hat die Stammressource noch keine ID. Daher wird das Schlüsselwort this im URI zur Darstellung der ID der Stammressource verwendet.

Beispiel für die Einschließung von Anforderungen für einfache hierarchische Beziehungen

Die folgenden Nutzdaten sind ein Beispiel für das Erstellen einer Aktivität auf dem Konto pc:10 und eine Notiz für diese Aktivität.

POST http://localhost:8180/pc/rest/account/v1/accounts/pc:10/activities

{
  "data": {
    "attributes": {
      "activityPattern": "general_reminder"
    }
  },
  "included": {
    "Note": [
      {
        "attributes": {
            "subject": "Initial phone call",
            "body": "Initial phone call with claimant"
        },
        "method": "post",
        "uri": "/common/v1/activities/this/notes"
      }
    ]
  }
}

Syntax für benannte Verhältnisse

In einigen Fällen ist das Verhältnis zwischen der Stammressource und einer eingeschlossenen Ressource mehr als nur ein hierarchisches Verhältnis. Es handelt sich um ein "benanntes Verhältnis", bei dem das Verhältnis eine spezielle Bezeichnung hat.

Beispielsweise hat jedes Konto einen "Kontoinhaber". Dies ist ein AccountContact, der der rechtmäßige Inhaber des Kontos ist. Ein Konto kann eine beliebige Anzahl untergeordneter AccountContacts haben, aber nur einer dieser AccountContacts kann als Kontoinhaber bezeichnet werden.

Wenn Sie die Einschließung von Anforderungen für benannte Verhältnisse verwenden, hat das JSON die folgende Struktur. Die Zeilen, die für einfache hierarchische Verhältnisse nicht erforderlich sind, aber für benannte Verhältnisse erforderlich sind, werden fett dargestellt:

{
  "data" : {
    "attributes": {
      "<relationshipField>": "<arbitraryRefId>"
      ...
    }
  },
  "included": {
    "<resourceType>": [
      {
        "attributes": {
          ...
        },
        "refid": "<arbitraryRefId>",
        "method": "post",
        "uri": "/../this/..."
      }
    ]
  }
}

Abschnitt data

Der Abschnitt data enthält Informationen über die Stammressource, z. B. ihre attributes. (Bei PATCHs kann der Abschnitt data auch einen Prüfsummenwert für die Stammressource enthalten.)

Der Abschnitt data enthält auch das Feld, das die Beziehung zur untergeordneten Ressource benennt. Dieses Feld ist auf eine Referenz-ID gesetzt. Der Wert dieser Referenz-ID ist willkürlich. Er kann ein beliebiger Wert sein, solange der Wert auch mit der untergeordneten Ressource im Abschnitt included angezeigt wird.

Abschnitt included

Der Abschnitt included besteht aus einem oder mehreren Unterabschnitten eingeschlossener Ressourcen. Jeder Unterabschnitt beginnt mit dem Namen des Ressourcentyps. Anschließend können eine oder mehrere Ressourcen dieses Typs angegeben werden. Für jede Ressource müssen Sie die folgenden Informationen angeben werden:

  • attributes der Ressource
  • method und uri zum Erstellen oder Ändern der Ressource.

Feld refid

Jede included Ressource muss Feld refid enthalten. Dieses Feld muss auf dieselbe beliebige Referenz-ID gesetzt werden, die im Abschnitt data verwendet wird. Die System-APIs verwenden refids, um zu ermitteln, welche untergeordnete Ressource im Abschnitt included das benannte Verhältnis zur Stammressource hat.

Felder method und uri.

Die Anforderungseinbindung umfasst einen einzelnen Aufruf eines einzelnen Endpunkts, aber die System-APIs verwenden intern mehrere Endpunkte, um den Aufruf auszuführen. Für jede eingeschlossene Ressource müssen Sie den für diese Ressource relevanten Vorgang und URI angeben.

Angenommen, Sie schreiben einen Aufruf POST /accounts, um ein Konto und einen AccountContact zu erstellen, der der "accountHolder" ist. Der AccountContact ist die eingeschlossene Ressource. Der Abschnitt included würde Code ähnlich dem folgenden enthalten:

"included": {
  "AccountContact": [
    {
      "attributes": {
        ...
      },
      "refid": "...",
      "method": "post",
      "uri": "/account/v1/accounts/this/contacts"
    }
  ]
}

Damit wird angegeben, dass zum Erstellen des AccountContact der Endpunkt /account/v1/{accountId}/contacts verwendet wird.

Der URI muss mit dem API-Namen beginnen, z. B. "/account/v1".

Der URI muss die ID der Stammressource angeben. Wenn die Stammressource und die eingeschlossenen Ressourcen gleichzeitig erstellt werden, hat die Stammressource noch keine ID. Daher wird das Schlüsselwort this im URI zur Darstellung der ID der Stammressource verwendet.

Beispiel für die Einschließung von Anforderungen für benannte Beziehungen

Die folgenden Nutzdaten sind ein Beispiel für das Erstellen eines Kontos und eines AccountContact für das Konto, dessen Verhältnis "accountHolder" lautet. (Konten erfordern auch einen primären Standort, sodass die Nutzdaten auch eine AccountLocation erstellt, dessen Verhältnis "primaryLocation" lautet.) Weitere Informationen zum Erstellen von Konten finden Sie unter Erstellen eines Kontos.

POST http://localhost:8180/pc/rest/account/v1/accounts

{
  "data": {
    "attributes": {
      "accountHolder": {
        "refid": "newperson"
      },
      "organizationType": {
        "code": "individual"
      },
      "preferredCoverageCurrency": {
        "code": "USD"
      },
      "preferredSettlementCurrency": {
        "code": "USD"
      },
      "primaryLocation": {
        "refid": "newloc"
      },
      "producerCodes": [
        {
          "id": "pc:6"
        }
      ]
    }
  },
  "included": {
    "AccountContact": [
      {
        "attributes": {
          "contactSubtype": "Person",
          "firstName": "Bill",
          "lastName": "Preston",
          "primaryAddress": {
            "addressLine1": "2850 S Delaware St #400",
            "city": "San Mateo",
            "postalCode": "94403",
            "state": {
              "code": "CA"
            }
          }
        },
        "method": "post",
        "refid": "newperson",
        "uri": "/account/v1/accounts/this/contacts"
      }
    ],
    "AccountLocation": [
      {
        "attributes": {
          "locationCode": "0001",
          "locationName": "Location 0001",
          "nonSpecific": true,
          "postalCode": "94403",
          "state": {
            "code": "CA"
          }
        },
        "method": "post",
        "refid": "newloc",
        "uri": "/account/v1/accounts/this/locations"
      }
    ]
  }
}

Zusätzliches Verhalten beim Einschließen von Anforderungen

PATCH und POST in einer einzigen Anforderung

Wenn Sie einen POST mit Anforderungseinschluss ausführen, muss der Vorgang für jede eingeschlossene Ressource ebenfalls POST sein.

Wenn Sie ein PATCH mit Anforderungseinschluss ausführen, kann der Vorgang für eine eingeschlossene Ressource entweder POST oder PATCH sein.

  • Wenn Sie eine vorhandene Ressource ändern und eine neue zugehörige Ressource erstellen möchten, lautet der POST-Vorgang der enthaltenen Ressource.
  • Wenn Sie eine vorhandene Ressource ändern und eine vorhandene zugehörige Ressource ändern möchten, ist der Vorgang der enthaltenen Ressource PATCH.

Anforderungen als Einheit erfolgreich oder fehlerhaft

Wenn ein POST oder PATCH die Einschließung von Anforderungen verwendet, kann entweder der Vorgang für die Stammressource oder der Vorgang für eine der eingeschlossenen Ressourcen fehlschlagen. Wenn ein Vorgang fehlschlägt, schlägt die gesamte Anforderung fehl, und keines der Objekte ist POSTed oder PATCHed.

Eingeschlossene Ressourcen können nicht auf andere Ressourcen als die Stammressource verweisen

Wenn Sie die Einschließung von Anforderungen verwenden, muss jede eingeschlossene Ressource ihren eigenen Vorgang und URI angeben. Es wird erwartet, dass der URI mit dem Schlüsselwort this auf die Stammressource verweist. Dadurch wird sichergestellt, dass die eingeschlossene Ressource mit der Stammressource verbunden ist, wenn es sich um POSTed oder PATCHed handelt.

Angenommen, ein POST erstellt ein Konto und einen AccountContact. Der URI für den AccountContact hätte einen Wert wie "/account/v1/accounts/this/contacts".

Aus Syntaxperspektive könnten Sie versuchen, eine eingeschlossene Ressource nicht an die Stammressource, sondern an eine andere vorhandene Ressource anzuhängen. Anstatt beispielsweise auf die Stammressource zu verweisen, könnte der URI für AccountContact auf ein vorhandenes Konto verweisen, z. B. "/account/v1/accounts/pc:20/contacts". In diesem URI heißt es: "Erstellen Sie einen AccountContact und fügen Sie ihn nicht an die Stammressource dieses POSTs an, sondern an das vorhandene Konto pc:20".

Die System-APIs lassen dies nicht zu. Jeder Versuch, eine eingeschlossene Ressource auf etwas Anderes als die Stammressource POST- oder PATCH-fähig zu machen, führt dazu, dass der Vorgang fehlschlägt.