Laden...

ASP.NET Core WebAPI: Gemeinsame Interfaces mit Routing

Erstellt von Palladin007 vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.227 Views
Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 5 Jahren
ASP.NET Core WebAPI: Gemeinsame Interfaces mit Routing

Guten Abend,

ich arbeite mich gerade in die Web-API von ASP.NET Core ein.
Meine ersten Versuche laufen auch alle, meine Frage ist eher kosmetischer Natur.

Vorher habe ich mit WCF gearbeitet und für jeden Service ein Interface in einer gemeinsam genutzten DLL abgelegt. Für den Web-Service gab's dann eine Implementierung, die tut, was sie eben tun soll und am Client hat WCF die Implementierung generiert.

Ich will im Prinzip sowas:

[Route("api/[controller]")]
public interface IValuesController
{
    [HttpGet]
    IEnumerable<string> Get();

    [HttpGet("{id}")]
    string Get(int id);

    [HttpPost]
    void Post([FromBody]string value);

    [HttpPut("{id}")]
    void Put(int id, [FromBody]string value);

    [HttpDelete("{id}")]
    void Delete(int id);
}

Das funktioniert so natürlich nicht, schon alleine, weil das Route-Attribute nur für Klassen erlaubt ist.

Der Server implementiert das und tut in jeder Methode, was er eben tun soll.
Am Client kann ich dann per Reflection auf diese per Attribut hinterlegten Informationen zugreifen und entsprechend die Requests zusammen bauen.
Ich will also irgendwie der Web-API mitteilen können, dass es die Attribute woanders suchen soll, nicht an der tatsächlichen Controller-Klasse, die Client-Implementierung baue ich dann mit RestSharp auf.

Das Ziel dahinter:
Ich will ein Interface (bzw. Mehrere) haben, das sowohl für Server als auch Client eindeutig und zwingend ist.
Wenn ich etwas am Server ändere, muss ich die Interfaces anpassen und kann nicht vergessen, das überall zu aktualisieren, weil der Compiler mich nicht bauen lässt.
Außerdem bin ich faul und will nicht immer alles doppelt schreiben müssen 😄

Hat da jemand eine Idee oder kennt einen besseren Weg?

Beste Grüße

T
2.222 Beiträge seit 2008
vor 5 Jahren

Meines Wissens nach wird dies nicht funktionieren.
Du sagst mit dem Controller nur auf Server Seite welche Verarbeitung er bei den entsprechend Verben verrichten soll.
Eine Verknüpfung, wie du Sie machen willst, funktioniert technisch nicht da der Client nicht wie bei WCF oder SOAP per XML kommuniziert und dort eine gemeinsame Basis vorhanden ist(Request/Respone Formate).
Hier wird auf reine HTTP Kommunikation mit den entsprechenden Verben + Parametern gesetzt.
Du Anbindung musst du immer auf Basis der aktuellen API Beschreibung machen.
Eine fertige Lösung per Reflektion wird auch nicht machbar sein, da es eben für den Client kein allgemeines Beschreibungsformat ala WSDL gibt.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 5 Jahren

Die gemeinsame Basis soll ja die gemeinsam genutzte DLL sein.

Die Client-Implementierung kann ich auch selber schreiben, da brauche ich keine fertige Lösung, RestSharp ist da schön flexibel, dass ich die Requests dynamisch zusammen bauen kann. Wenn es eine fertige Lösung gibt, wäre das natürlich schön, aber wenn Frameworks wie Refit alles automatisch schaffen, wird sich da schon ein Weg finden.

Das "Einzige", was ich brauche, ist, dass ASP.NET Core die Attribut-basierten Routings in einem anderen Typ sucht. Ich gebe sozusagen als Controller nicht mehr die Klasse, sondern ein Interface und liefere auf einem anderen Weg (z.B. Factory) die Implementierung dazu. Bei jedem Aufruf sucht ASP.NET Core in diesem Interface nach der passenden Methode und ruft die dann anhand der von mir gelieferten Instanz auf.
So zumindest meine laienhafte Vorstellung.

Als Altenrative fällt mir nur ein, dass ich besagte Attribute selber definiere und die Routings dann automatisch anhand dieser Attribute eintragen lasse. Zumindest habe ich Beispiele für ein fluentartiges Routing-Mapping gesehen, das müsste ja auch dynamisch funktionieren.

Alles Weitere (gemeinsame Basis beschaffen, Client-Implementierung, etc.) kann ich dann selber machen.

Beide Anwendungen (Server und Client) kommen direkt von mir und die werden auch immer von mir (bzw. Kollegen) kommen, wir haben also immer Zugriff auf den Code.
Wenn so ein REST-Service online frei verfügbar wäre, klar, dann macht das überhaupt keinen Sinn, aber ich brauche das nur zur Kommunikation zwischen zwei EIgenentwicklungen.

P
441 Beiträge seit 2014
vor 5 Jahren

Es gibt auch für RESTful API's eine gemeinsame Beschreibungssprache, das OpenAPI Format.
Für .NET und ASP.NET (inkl. Core) gibt es sogar mehrere Toolings, z.B. NSwag.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 5 Jahren

Das heißt, ich muss mir erst vom Server eine Beschreibung der API im OpenAPI-Format generieren lassen um dann am Client daraus die Implementierung zu bauen, obwohl der komplette Code für die Server-Anwendung nur einen Ordner weiter ist?

P
441 Beiträge seit 2014
vor 5 Jahren

Vom Prinzip ja.
Du kannst die API Beschreibung (ähnlich wie das wsdl) auch vom Server dynamisch generieren lassen und dann deinen Client Code daraus generieren. Ist - finde ich - einfacher, als die DTO's in einer Shared Lib zu halten.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 5 Jahren

WCF bietet sowas auch an und ich bin nie wirklich warm damit geworden.
Stattdessen hab ich die DTOs an einer gemeinsamen DLL abgelegt und musste gar nichts weiter machen, aber wenn ASP.NET sowas nicht bietet ... schade.