Website-Suche

typescript - Typensicheres Verwenden eines OData v3-Anbieters


Ich habe einen OData v3-Anbieter, den ich von einer TypeScript-App aus typsicher nutzen möchte. Idealerweise möchte ich einen Client aus den Metadaten des Anbieters generieren.

Das Problem ist, dass v3 nicht so verbreitet ist wie v2 und v4, daher habe ich keinen Weg gefunden, dies zu tun.

Was ich versucht habe:

odata2ts

Diese Bibliothek unterstützt nur die Spezifikationen v2 und v4. Das Hauptkompatibilitätsproblem besteht darin, dass v3 mit Daten unter response.data.value antwortet, während v2 und v4 andere Formate verwenden.

Es gibt eine Funktionsanfrage für die v3-Unterstützung. Es scheint jedoch, dass dies in naher Zukunft nicht umgesetzt wird.

Als Lösung empfiehlt ein Mitwirkender der Bibliothek, das Format application/json;odata=verbose zu verwenden, wenn man mit v3-Anbietern arbeitet. Der Anbieter, den ich jedoch nutze, unterstützt ein solches Format nicht und verwendet immer den Datenpfad response.data.value.

OData-Spezifikation in OpenAPI konvertieren

Zuerst habe ich die Spezifikation von OData in OpenAPI konvertiert. Dafür habe ich odata-openapi verwendet.

Dann habe ich openapi-typescript-codegen verwendet, um einen TypeScript-Client basierend auf der oben generierten Spezifikation zu erstellen.

Das Hauptproblem bei diesem Ansatz ist, dass OData das Format Collection(id) verwendet, um auf ein Element dieser Sammlung zu verweisen. In der generierten OpenAPI-Spezifikation gibt es für eine Sammlung zwei Pfade: /Collection und /Collection({id}). Der aus dieser Spezifikation generierte Client sieht ungefähr so aus:

export class CollectionService {

/** ... */

// No additional parenthesis as the path is just /Collection
public static getCollection(/** ... */) {/** ... */}

// This is not valid TypeScript code. First parentheses come from parentheses inside path /Collection({id})
public static getCollection()(id: string, /** ... */) {/** ... */}

/** ... */

}

Übersetzen von v3 in v2 oder v4

Bei einer schnellen Suche habe ich Teiid entdeckt. Ich nehme an, dass dies als Übersetzungsschicht zwischen meinem OData v3-Anbieter und odata2ts verwendet werden kann.

odata2ts könnte mit teiid kommunizieren, das dann die Anfragen in die v3-Spezifikation für den OData-Anbieter übersetzen würde.

Ich denke, dies ist die logischste Lösung dafür. Allerdings verkompliziert das die Anwendung um ein Vielfaches. Ich habe versucht, Teiid einzurichten, habe aber schnell die Geduld verloren. Es gibt einfach zu viele Komponenten.

Aktualisieren

Teiid unterstützt OData v3 nicht, obwohl in den Dokumenten behauptet wird, dass es dies tut.

Der OData-Übersetzer, bekannt unter dem Typnamen "odata", stellt die OData V2- und V3-Datenquellen bereit und verwendet den Teiid-Webservices-Ressourcenadapter, um Webservice-Aufrufe durchzuführen. Dieser Übersetzer ist eine Erweiterung des Webservices-Übersetzers.

Mein Setup:

  • Wildfly 19.1.0
  • Teiid Wildfly 16.0.0

Ich habe eine Verbindung (ich nehme an, sie wird so genannt) mit dem Namen s1c unter Verwendung der folgenden Befehle innerhalb von jboss-cli erstellt:

batch
/subsystem=resource-adapters/resource-adapter=webservice/connection-definitions=s1c:add(jndi-name=java:/s1c, class-name=org.teiid.resource.adapter.ws.WSManagedConnectionFactory, enabled=true, use-java-context=true)
/subsystem=resource-adapters/resource-adapter=webservice/connection-definitions=s1c/config-properties=EndPoint:add(value="http://localhost/college/odata/standard.odata")
/subsystem=resource-adapters/resource-adapter=webservice/connection-definitions=s1c/config-properties=SecurityType:add(value="HTTPBasic")
/subsystem=resource-adapters/resource-adapter=webservice/connection-definitions=s1c/config-properties=AuthUserName:add(value="admin")
/subsystem=resource-adapters/resource-adapter=webservice/connection-definitions=s1c/config-properties=AuthPassword:add(value="admin")
/subsystem=resource-adapters/resource-adapter=webservice:activate
runbatch

Und eine virtuelle Datenbank bereitgestellt, die mit XML definiert ist:

<vdb name="s1c" version="1">
    <model name="s1c">
        <source connection-jndi-name="java:/s1c" name="s1c-connector" translator-name="odata"/>
    </model>
</vdb>

Danach habe ich den Wildfly-Server neu gestartet, und diese Warnung erscheint im Terminal:

13:25:33,355 WARN  [org.teiid.RUNTIME] (Worker0_async-teiid-threads0)  TEIID50036 VDB s1c.1 model "s1c" metadata failed to load. Reason:Unknown ODataVersion 3.0

Also, ich nehme an, dass du Teiid dafür nicht verwenden kannst.

Meine Erwartungen

Mein Hauptziel ist es, einen automatisch generierten typsicheren Client für die Kommunikation mit einem OData v3-Provider zu haben. Der Client kann jede Methode nutzen, um das Ziel zu erreichen: sei es eine andere Spezifikation oder eine Übersetzungsschicht.

Die Dinge, die ich nicht ändern oder opfern kann oder will:

  • Der Anbieter verwendet OData v3.
  • Die Kommunikation mit dem Anbieter muss über eine typsichere Wrapper erfolgen, die aus den Metadaten des Anbieters generiert wird.

Jeglicher Rat oder jede Meinung wäre sehr geschätzt.