Ankündigung

Einklappen
Keine Ankündigung bisher.

Mix aus REST und RPC

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Mix aus REST und RPC

    Hi,

    seit ziemlich langer Zeit ist REST der letzte Schrei und RPC recht verpöhnt. Allerdings stelle ich mir die Frage, was das Problem wäre, beides zu mixen. Bsp.:

    * Alle lesenden Requests REST-like
    * Schreibende Requests RPC-like

    In der Umsetzung wäre das dann etwa:
    POST /users/register
    PATCH /users/<id oder was auch immer> oder eben auch POST /users/<id oder was auch immer>/update oder so
    GET /users/<id oder was auch immer>
    ...

    Das sind keine finalen Endpunkte, sondern nur Ideen zur Verdeutlichung

    Hat jemand so etwas schon mal umgesetzt? Der Vorteil wäre, dass man Daten- und Workflow-basierte Use-Cases sauberer abbilden kann.

    Der eine oder andere denkt jetzt vermutlich "BUHH - Dann plane Deine API besser" oder "Never mix different things up". Beides valide Standpunkte. Aber ich denke, es lohnt sich, mal über den Tellerrand der eigenen Meinung zu schauen

  • #2
    Rest basiert auf Resourcen, nicht auf Aktionen oder Methoden.
    Anders als bei vielen verwandten Architekturen kodiert REST keine Methodeninformation in den URI, da der URI Ort und Namen der Ressource angibt, nicht aber die Funktionalität, die der Web-Dienst zu der Ressource anbietet. Der Vorteil von REST liegt darin, dass im WWW bereits ein Großteil der für REST nötigen Infrastruktur (z. B. Web- und Application-Server, HTTP-fähige Clients, HTML- und XML-Parser, Sicherheitsmechanismen) vorhanden ist, und viele Web-Dienste per se REST-konform sind. Eine Ressource kann dabei über verschiedene Medientypen dargestellt werden, auch Repräsentation der Ressource genannt.
    Jedoch hast du recht, dass es tatsächlich der Fall sein kann, dass nur eine Aktion sinnvoll eingesetzt werden kann und eine Resource einfach nicht die Möglichkeit bietet, die man braucht (oder nur sehr umständlich). Ich habe also tatsächlich mal eine Kombination umgesetzt. Allerdings habe ich es etwas anders gemacht. Bei mir ist eine Action immer mit einem POST-Verb verbunden, z.B.:
    POST /actions/password-recovery

    RPC oder Actions, wie es bei mir heißt, kommen immer dann zum Einsatz, wenn die Berechtigungsstruktur es verbietet, die Resource direkt abzugreifen oder zu verändern. Eine Passwort Vergessen Funktion ändert die /users Resource, aber ein PUT auf die /users ist berechtigungsmäßig eingeschränkt, daher kann ich das als nicht angemeldeter Benutzer nicht einfach ausführen.

    Das was du als Beispiel genommen hast (/users/<id>/update) ist ein eher schlechtes Beispiel für einen RPC, denn hier wäre im Sinne von REST ein PUT /users/<id> viel sinniger, da du die User-Resource veränderst.


    Noch ein Tipp: Falls du eine REST-Schnittstelle implementierst, halte dich an einen Standard und mach es nicht irgendwie. Das vermindert die Chance, dass du Mist machst... Schau dir z.B. mal http://jsonapi.org an, dieser Standard ist recht gut dokumentiert und auch durchdacht.
    Tutorials zum Thema Technik:
    https://pilabor.com
    https://www.fynder.de

    Kommentar


    • #3
      Rest basiert auf Resourcen, nicht auf Aktionen oder Methoden.
      Auf HTTP-Methoden
      wenn die Berechtigungsstruktur es verbietet, die Resource direkt abzugreifen oder zu verändern
      Was meinst Du? Das eine hat doch mit dem anderen nichts zu tun.

      Das was du als Beispiel genommen hast (/users/<id>/update) ist ein eher schlechtes Beispiel für einen RPC, denn hier wäre im Sinne von REST ein PUT /users/<id> viel sinniger, da du die User-Resource veränderst.
      Du hast recht - Ich wollte nur eine potentielle Alternative zum REST-Ansatz zeigen.

      Falls du eine REST-Schnittstelle implementierst, halte dich an einen Standard und mach es nicht irgendwie
      Darum geht es ja gerade. Wie Du schon oben geschrieben hast, gibt es manchmal Dinge, die sich semantisch mit REST nur schlecht abbilden lassen.

      Der jsonapi-"Standard" hat m. E. n. nichts mit der Frage zu tun.

      Kommentar


      • #4
        Auf HTTP-Methoden
        Du vermischst Konzeption und technische Implementierung... Nur weil man sich darauf geeinigt hat, dass HTTP-Methoden mit einer Aktion in Verbindung stehen, z.B. das POST mit "neuen Datensatz anlegen" gleichzusetzen ist, sind HTTP-Methoden nicht mit REST gleichzusetzen. Bei REST geht es um eine Kombination und das Zusammenspiel von Unified Resource Identifier (URI), HTTP-Methoden, Request und Response-Headern, Datensätzen und vielem mehr.

        Was meinst Du? Das eine hat doch mit dem anderen nichts zu tun.
        Puh, wo soll ich da anfangen... ich versuche dir mal ein veranschaulichendes Beispiel zu geben.

        Die Resource /users verweist auf die Entität User, sprich: Einen Benutzer. Nach REST-Konvention könnte man jetzt folgendes annehmen:

        POST /users => legt einen neuen Benutzer an
        GET /users => liefert eine Liste aller Benutzer
        GET /users/1 => liefert den Benutzer mit ID 1
        PUT /users/1 => Verändert den kompletten Datensatz des Benutzers mit der ID 1
        PATCH /users/1 => Verändert einzelne Attribute des Benutzers mit der ID 1
        DELETE /users/1 => Löscht den Benutzer 1
        DELETE /users => Löscht alle Benutzer

        Es geht meiner Ansicht nach bei REST eher darum, dass man einen klaren Identifier für Entitäten und somit einen strukturierten Aufbau hat und nicht mit RPC-Methoden prinzipiell an jeder Entität Änderungen vornehmen kann, ohne diese nachverfolgen zu können. Bei REST gibt es immer definierte Aktionen (POST, GET, PUT, DELETE, PATCH, etc.), die auf eine Resource bzw. einen Datensatz via URI ausgeführt werden (z.B. /users, /roles, /addresses, etc.). Man Arbeitet also eher mit Datensätzen, als mit Abläufen. Diese Beschränkung vereinfacht vieles, macht aber auch einiges komplizierter.

        Nach dieser Definition könnte man eine Registrierung z.B. eigentlich als Neuanlage eines Benutzers sehen. Also:
        POST /users

        Daraus ergibt sich aber ein Problem. Und zwar kann man jetzt streng genommen nicht mehr zwischen der administrativen Funktion "Benutzer anlegen" und der öffentlichen Funktion "Registrieren" unterscheiden. Natürlich kann man jetzt
        POST /registration
        verwenden, jedoch verkompliziert das die Sache etwas. Weil die Entität Registration statt User verwendet werden muss und bei der Bestätigung der Registrierung diese z.B. von der Tabelle "Registrations" in die Tabelle "Users" überführt werden muss.

        Langer Rede, kurzer Sinn: RPC sind unter Umständen sinnvoll, insbesondere bei Resourcen, die mehrere Aufgaben erfüllen können und auf die verschiedene Berechtigungen bestehen.


        Darum geht es ja gerade. Wie Du schon oben geschrieben hast, gibt es manchmal Dinge, die sich semantisch mit REST nur schlecht abbilden lassen. Der jsonapi-"Standard" hat m. E. n. nichts mit der Frage zu tun.
        Vermutlich ist unterm Strich die Erkenntnis, dass REST eben manchmal nicht reicht, maßgeblich. Dem stimme ich in Teilen zu. Eine Vermischung von REST und RPC ist aber meiner Ansicht nach nicht zu empfehlen.

        Das hier z.B.:
        * Alle lesenden Requests REST-like
        * Schreibende Requests RPC-like
        würde ich als extrem verwirrend empfinden. Insbesondere weil REST alle Aktionen für eine Resource bereits vorgibt, sind "schreibende" Requests mit PUT, POST und PATCH eigentlich auch vorgegeben. Und zwar nicht als RPC, sondern als REST.

        Eine notwendige Erweiterung um RPC finde ich nur sinnvoll, wenn diese nicht einfach dazu geschustert wird, sondern auch einer klaren Definition folgt. Es spricht ja nichts dagegen, beides gleichzeitig anzubieten:

        POST /api/rest/users => legt neuen Benutzer an
        POST /api/json-rpc { "method": "sum", "params": {"a":3, "b":4}, "id":0}} => summiert Werte

        Tutorials zum Thema Technik:
        https://pilabor.com
        https://www.fynder.de

        Kommentar


        • #5
          sind HTTP-Methoden nicht mit REST gleichzusetzen.
          ? Das ist ein elementarer Bestandteil von REST - Mit standardisierten Methoden auf Ressourcen arbeiten.

          Es geht meiner Ansicht nach bei REST eher darum, dass man einen klaren Identifier für Entitäten und somit einen strukturierten Aufbau hat und nicht mit RPC-Methoden prinzipiell an jeder Entität Änderungen vornehmen kann, ohne diese nachverfolgen zu können.
          Aber immer noch hat die Berechtigung oder Logging oder was Du mit Nachverfolgen meinst, nichts mit REST oder RPC zu tun. Nur, dass RPC benutzt wird, heißt doch nicht zwangsläufig, dass man damit ohne Beschränkung alles machen kann. Oder verstehe ich Dich falsch?

          Weil die Entität Registration statt User verwendet werden muss und bei der Bestätigung der Registrierung diese z.B. von der Tabelle "Registrations" in die Tabelle "Users" überführt werden muss.
          Das würde ich jetzt nicht unbedingt sagen. Eine externe Ressource muss nicht unbedingt intern ein Gegenstück haben.

          Und zwar kann man jetzt streng genommen nicht mehr zwischen der administrativen Funktion "Benutzer anlegen" und der öffentlichen Funktion "Registrieren" unterscheiden
          Und genau hier kommt mein Gedanke zum tragen: Wenn ich etwas _mache_, dann ist das ein Use-Case. Einen neuen Benutzer will ich nicht per se "hinzufügen", sondern eben z. B. "registrieren", was semantisch verschiedene Dinge sein können. Mich interessiert eigentlich nicht, ob ich da eine Ressource anlege, sondern ich möchte semantisch korrekt eine Aktion durchführen (semantisch im Sinne der Fachdomäne.) - Und hier ist meiner Meinung nach RPC semantisch flexibler.

          Wenn ich den User, der wie auch immer angelegt wurde lesen will, greife ich jedoch in der Tat auf dieses Objekt zu - Daher denke ich, dass man hier durchaus den REST-Ansatz des Abfragens von Ressourcen nutzen kann/sollte

          Kommentar


          • #6
            ? Das ist ein elementarer Bestandteil von REST - Mit standardisierten Methoden auf Ressourcen arbeiten.
            Damit meine ich nur: REST beinhaltet deutlich mehr, als nur die Nutzung von HTTP-Verben / Methoden.

            Aber immer noch hat die Berechtigung oder Logging oder was Du mit Nachverfolgen meinst, nichts mit REST oder RPC zu tun. Nur, dass RPC benutzt wird, heißt doch nicht zwangsläufig, dass man damit ohne Beschränkung alles machen kann. Oder verstehe ich Dich falsch?
            Das Beispiel mit den Berechtigungen habe ich angeführt, weil man mit diesem Beispiel an die Grenzen von REST stößt. Eine Resource sollte sich möglichst immer gleich verhalten, solange der gleiche Request an sie gestellt wird, aber wenn es ein Login gibt, ist das nicht mehr so richtig der Fall, da angemeldete / berechtigte Benutzer andere Ergebnisse erhalten, als nicht angemeldete / unberechtigte.

            RPC führt Logik aus, REST persistiert oder liest im wesentlichen Entitäten. Logik ausführen bedeutet in dem Fall, dass prinzipiell alles möglich ist. Daten verschieben, Berechnungen ausführen, etc. Natürlich kann man auch einfach nur Logik zum Persistieren oder Lesen ausführen...man ist aber weniger eingeschränkt und neigt dadurch dazu, Dinge zu tun, die man vielleicht nicht tun sollte.
            Daher denke ich, ist REST so beliebt. Es ist einfach zu verstehen und sehr intuitiv.


            Um das ganze (für mich) abzuschließen: Deine Ursprungsfrage bezieht sich darauf, was das Problem wäre, beides zu mixen. Technisch ist das sicher kein Problem. Meiner Meinung nach besteht das Problem eher in der Nutzung der resultierenden API. Eine API soll meiner Ansicht nach leicht zu verstehen, intuitiv zu bedienen, gut dokumentiert und bestenfalls einfach zu erweitern sein (neben weiteren Kriterien, wie guter Performance, etc.). Wenn man beides mischt, finde ich, dass es die Umsetzung all dieser Anforderungen erschwert. Daher auch der Verweis auf die Verwendung eines RFC oder eines existierenden Standards. Wenn man sich an so etwas hält, kriegt man Teile der Dokumentation gratis und dazu viele Gedanken, die sich andere bereits gemacht haben und passende Problemlösungen für viele Dinge. Es hilft auch, die RFCs zu diesen Themen einfach mal zu lesen... dadurch versteht man die Gründe vieler Entscheidungen besser.

            Meine Meinung: Wenn alles gleich funktioniert und einem einheitlichen Konzept folgt, finde ich das als Programmierer immer sehr angenehm. Wenn nicht, finde ich es nervig, Sonderfälle zu implementieren. Insbesondere, wenn ich mich dann mit 2 Standards beschäftigen muss, statt mit einem.
            Tutorials zum Thema Technik:
            https://pilabor.com
            https://www.fynder.de

            Kommentar


            • #7
              Auch von mir abschließend : Ich bin noch mal meine Use-Cases durchgegangen und tatsächlich lässt sich alles über virtuelle Ressourcen abbilden. Man sollte natürlich vorsichtig sein, dass das nicht ausufert, aber das zwingt dann gleichzeitig zum Nachdenken, ob die Business-Logik nicht überkompliziert wurde.

              Danke für Deinen Input.

              Kommentar

              Lädt...
              X