typescript - Typsäkert konsumera en OData v3-leverantör


Jag har en OData v3-leverantör, som jag vill konsumera på ett typsäkert sätt från en TypeScript-app. Helst vill jag generera en klient från leverantörens metadata.

Problemet är att v3 inte är lika vanlig som v2 och v4, så jag har inte lyckats hitta ett sätt att göra det.

Vad jag har försökt:

odata2ts

Detta bibliotek stöder endast v2- och v4-specifikationer. Huvudproblemet med kompatibilitet är att v3 svarar med data under response.data.value, medan v2 och v4 använder olika format.

Det finns en funktionsförfrågan för v3-stöd. Det verkar dock som att detta inte kommer att implementeras inom den närmaste framtiden.

Som en lösning rekommenderar en bidragsgivare till biblioteket att använda application/json;odata=verbose-formatet när man hanterar v3-leverantörer. Men leverantören jag använder stöder inte ett sådant format och använder alltid response.data.value-datavägen.

Konvertera OData-specifikation till OpenAPI

Först konverterade jag specifikationen från OData till OpenAPI. För det använde jag odata-openapi.

Sedan använde jag openapi-typescript-codegen för att generera en TypeScript-klient baserat på den genererade specifikationen ovan.

Det största problemet med detta tillvägagångssätt är att OData använder Collection(id)-formatet för att referera till en enhet i denna samling. I den genererade OpenAPI-specifikationen finns det två vägar för en samling: /Collection och /Collection({id}). Den genererade klienten från denna specifikation ser ungefär ut så här:

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, /** ... */) {/** ... */}

/** ... */

}

Översätter v3 till v2 eller v4

Från en snabb sökning har jag upptäckt teiid. Jag antar att detta kan användas som ett översättningslager mellan min OData v3-leverantör och odata2ts.

odata2ts kunde kommunicera med teiid, som sedan skulle översätta förfrågningarna till v3-specifikationen för OData-leverantören.

Jag tycker att detta är den mest logiska lösningen på detta. Dock komplicerar detta applikationen väldigt mycket. Jag försökte sätta upp teiid, men tappade snabbt tålamodet. Det finns helt enkelt för många komponenter.

Uppdatera

Teiid stöder inte OData v3 trots att det påstås i dokumentationen.

OData-översättaren, känd under typenamnet "odata", exponerar OData V2 och V3 datakällor och använder Teiid webbtjänstresursadapter för att göra webbtjänstermodtagningar. Denna översättare är en förlängning av webbtjänstöversättaren.

Min uppställning:

  • Wildfly 19.1.0
  • Teiid Wildfly 16.0.0

Jag skapade en anslutning (jag antar att det kallas så) med namnet s1c med följande kommandon i jboss-cli:

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

Och driftsatte en virtuell databas definierad med xml:

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

Efter det startade jag om Wildfly-servern, och denna varning dyker upp i terminalen:

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

Så, jag antar att du inte kan använda Teiid för detta.

Mina förväntningar

Mitt huvudmål är att ha en automatiskt genererad typ-säker klient för att kommunicera med en OData v3-leverantör. Klienten kan använda vilket medel som helst för att uppnå målet: vare sig det är en annan specifikation eller ett översättningslager.

De saker jag inte kan eller är villig att förändra/offra:

  • Leverantören använder OData v3.
  • Kommunikation med leverantören måste ske genom ett typ-säkert wrapper som genereras från leverantörens metadata.

Alla råd eller åsikter skulle uppskattas mycket.