REST- oder RESTful-API-Design – Wie funktioniert es?
Das REST- oder RESTful-API-Design (Representational State Transfer) wurde entwickelt, um die Vorteile bestehender Protokolle zu nutzen. Während REST über nahezu jedes Protokoll verwendet werden kann, nutzt es in der Regel die Vorteile von HTTP, wenn es für Web-APIs verwendet wird. Das bedeutet, dass Du als Entwickler keine Bibliotheken oder zusätzliche Software installieren musst, um die Vorteile eines REST-API-Designs zu nutzen.
Was ist REST?
Das REST API Design wurde von Dr. Roy Fielding in seiner 2000 abgeschlossenen Doktorarbeit definiert. Es zeichnet sich durch seine unglaubliche Flexibilität aus. Da Daten nicht an Methoden und Ressourcen gebunden sind, hat REST die Fähigkeit, mehrere Arten von Aufrufen zu verarbeiten, verschiedene Datenformate zurückzugeben und sich sogar strukturell mit der richtigen Implementierung von Hypermedien zu ändern.
Diese Freiheit und Flexibilität, die dem REST-API-Design innewohnt, ermöglicht es Dir, eine API zu entwickeln, die Deinen Bedürfnissen entspricht und gleichzeitig die Bedürfnisse der unterschiedlichsten Kunden erfüllt. Im Gegensatz zu SOAP ist REST nicht auf XML beschränkt, sondern kann XML, JSON, YAML oder jedes andere Format zurückgeben, je nachdem, was der Client anfordert. Und im Gegensatz zu RPC müssen Benutzer keine Prozedurnamen oder bestimmte Parameter in einer bestimmten Reihenfolge kennen.
Es gibt jedoch Nachteile beim Design der REST-API. Sie können die Fähigkeit verlieren, den Status in REST aufrechtzuerhalten, zum Beispiel innerhalb von Sitzungen. Es ist auch wichtig zu verstehen, was eine REST-API RESTful macht und warum diese Einschränkungen bestehen, bevor Du Deine API erstellst.
Wie funktioniert REST? Was ist eine REST-API?
Während die meisten APIs behaupten, RESTful zu sein, bleiben sie hinter den Anforderungen und Einschränkungen zurück, die Dr. Fielding geltend macht. Es gibt sechs wesentliche Einschränkungen für das REST-API-Design, die Du beachten musst, wenn Du entscheidest, ob dies der richtige API-Typ für Dein Projekt ist.
Client-Server
Die Client-Server-Beschränkung arbeitet mit dem Konzept, dass der Client und der Server getrennt voneinander sein sollten und sich individuell und unabhängig entwickeln können. Du willst in der Lage sein, Änderungen an Deiner mobilen Anwendung vorzunehmen, ohne die Datenstruktur oder das Datenbankdesign auf dem Server zu beeinflussen. Gleichzeitig sollte es Dir möglich sein, die Datenbank zu modifizieren oder Änderungen an der Serveranwendung vorzunehmen, ohne den mobilen Client zu beeinträchtigen. Dies schafft eine Trennung, sodass jede Anwendung unabhängig voneinander wachsen und skaliert werden kann.
Zustandslos
REST-APIs sind zustandslos. Aufrufe können unabhängig voneinander erfolgen und jeder Aufruf enthält alle Daten, die für eine erfolgreiche Durchführung erforderlich sind. Eine REST-API sollte sich nicht darauf verlassen, dass Daten auf dem Server oder in Sitzungen gespeichert werden, um zu bestimmen, was mit einem Anruf zu tun ist, sondern sich ausschließlich auf die Daten verlassen, die in diesem Aufruf selbst bereitgestellt werden. Identifizierungsinformationen werden nicht auf dem Server gespeichert. Stattdessen hat jeder Aufruf die notwendigen Daten in sich, wie zum Beispiel API-Schlüssel, Zugriffstoken, Benutzer-ID, etc. Dies trägt auch dazu bei, die Zuverlässigkeit der API zu erhöhen, da alle für den Aufruf notwendigen Daten vorhanden sind, anstatt sich auf eine Reihe von Aufrufen mit Serverstatus zu verlassen, um ein Objekt zu erstellen, was zu Teilausfällen oder inkonsistenten Daten führen kann. Um den Speicherbedarf zu reduzieren und Deine Anwendung so skalierbar wie möglich zu halten, erfordert eine RESTful-API, dass jeder Zustand auf dem Client gespeichert wird – nicht auf dem Server.
Cache
Da eine zustandslose API den Anfrage-Overhead erhöhen kann, sollte eine REST-API entwickelt werden, um die Speicherung von zwischenspeicherbaren Daten zu fördern. Das bedeutet, dass, wenn Daten zwischengespeichert werden können, die Antwort darauf hinweisen sollte, dass die Daten bis zu einem bestimmten Zeitpunkt (expires-at) gespeichert werden können, oder in Fällen, in denen Daten in Echtzeit vorliegen müssen, dass die Antwort nicht vom Client zwischengespeichert werden sollte. Durch die Aktivierung dieser kritischen Einschränkung reduzierst Du nicht nur die Anzahl der Interaktionen mit der API erheblich und reduzierst so die interne Serverauslastung, sondern stellst den API-Benutzern auch die notwendigen Werkzeuge zur Verfügung, um die schnellsten und effizientesten Anwendungen bereitzustellen. Beachte dabei immer, dass das Caching auf der Client-Seite durchgeführt wird.
Einheitliche Schnittstelle
Der Schlüssel zur Entkopplung des Clients vom Server ist eine einheitliche Schnittstelle, die eine unabhängige Entwicklung der Anwendung ermöglicht, ohne dass die Dienste, Modelle oder Aktionen der Anwendung eng mit der API-Schicht selbst gekoppelt sind. Die einheitliche Benutzeroberfläche ermöglicht es dem Client, mit dem Server in einer einzigen Sprache zu kommunizieren, unabhängig vom Architektur-Backend beider Sprachen. Diese Schnittstelle sollte eine unveränderliche, standardisierte Kommunikation zwischen dem Client und dem Server ermöglichen, zum Beispiel die Verwendung von HTTP mit URI-Ressourcen, CRUD (Create, Read, Update, Delete) und JSON.
Schichtensystem
Wie der Name schon sagt, ist ein Schichtensystem ein System, das aus Schichten besteht, wobei jede Schicht eine spezifische Funktionalität und Verantwortung hat. Jede Schicht ist getrennt, interagiert aber auch mit der anderen. Beim REST-API-Design gilt das gleiche Prinzip, wobei verschiedene Schichten der Architektur zusammenarbeiten, um eine Hierarchie aufzubauen, die dazu beiträgt, eine skalierbarere und modularere Anwendung zu erstellen.
Ein mehrschichtiges System ermöglicht es Dir auch, Legacy-Systeme zu kapseln und weniger häufig genutzte Funktionen an einen gemeinsamen Zwischenhändler zu übertragen, während Du gleichzeitig modernere und häufig verwendete Komponenten vor ihnen schützt. Darüber hinaus gibt Dir das geschichtete System die Freiheit, Systeme in und aus Deiner Architektur zu verschieben, wenn sich Technologien und Dienste weiterentwickeln. Dies erhöht die Flexibilität und Langlebigkeit, solange Du die verschiedenen Module so lose wie möglich gekoppelt hältst. Es gibt erhebliche Sicherheitsvorteile durch ein mehrschichtiges System, da es Dir ermöglicht, Angriffe auf der Proxy-Schicht oder innerhalb anderer Schichten zu stoppen und sie daran zu hindern, zur eigentlichen Serverarchitektur zu gelangen. Durch die Verwendung eines mehrschichtigen Systems mit einem Proxy oder die Einrichtung eines einzigen Zugangspunktes bist Du in der Lage, kritische und anfälligere Aspekte der Architektur hinter einer Firewall zu halten und eine direkte Interaktion mit ihnen durch den Client zu verhindern.
Code on Demand
Code on Demand, die vielleicht am wenigsten bekannte der sechs Beschränkungen und die einzige optionale Einschränkung, ermöglicht die Übertragung von Code oder Applets über die API zur Verwendung innerhalb der Anwendung. Im Wesentlichen schafft sie eine intelligente Anwendung, die nicht mehr nur von ihrer eigenen Code-Struktur abhängig ist.
Eigenschaften und Besonderheiten von REST
Zusammen bilden diese Einschränkungen die Theorie des Representational State Transfer, kurz REST. Jede aufeinanderfolgende Einschränkung baut auf der vorherigen auf und schafft schließlich eine ziemlich komplexe, aber leistungsstarke und flexible Programmoberfläche. Aber vor allem bilden diese Einschränkungen ein Design, das ähnlich funktioniert wie der Zugriff auf Seiten in unseren Browsern im World Wide Web. Es erstellt eine API, die nicht durch ihre Architektur, sondern durch die von ihr zurückgegebenen Darstellungen bestimmt wird, und eine API, die – während sie architektonisch zustandslos ist – auf die Darstellung angewiesen ist, um den Zustand der Anwendung zu bestimmen.
Wie kann ich REST beim Entwickeln nutzen?
Ob es technisch RESTful ist oder nicht (gemäß den sechs zuvor genannten Einschränkungen), kannst Du REST einfach beim Entwickeln nutzen.
1. Nutze HTTP-Verben, um Deine Anfragen so zu gestalten, dass sie etwas bedeuten.
API-Konsumenten sind in der Lage, GET-, POST-, PUT- und DELETE-Verben zu senden, was die Übersichtlichkeit einer bestimmten Anfrage erheblich verbessert.
2. Bereitstellung sinnvoller Ressourcennamen
Die Herstellung einer großartigen API ist zu 80 % Kunst und zu 20 % Wissenschaft. Das Erstellen einer URL-Hierarchie, die sensible Ressourcen repräsentiert, ist der Kunstteil. Sinnvolle Ressourcennamen (die nur URL-Pfade sind, wie zum Beispiel /kunden/12345/bestellungen) verbessern die Klarheit darüber, was eine bestimmte Anfrage bewirkt.
3. Entwickle für Deine Kunden, nicht für die Daten.
Ressourcennamen sollten Substantive sein. Vermeide Verben als Ressourcennamen, um die Übersichtlichkeit zu verbessern. Verwende die HTTP-Methoden, um den Verb-Anteil der Anforderung anzugeben.
4. Halte die URLs so kurz wie möglich, mit so wenigen Segmenten wie möglich.
5. Verwende HTTP Response Codes, um den Status anzuzeigen.
6. Biete sowohl JSON als auch XML an.
Fazit
Zu Beginn ist es am besten, APIs zu erstellen, die die zugrunde liegende Anwendungsdomäne oder Datenbankarchitektur Ihres Systems nachahmen. Schließlich werden Sie aggregierte Dienste benötigen, die mehrere zugrundeliegende Ressourcen nutzen, um die Kommunikation zu reduzieren. Es ist jedoch viel einfacher, später aus einzelnen Ressourcen größere Ressourcen zu erstellen, als aus größeren Aggregaten feinkörnige oder einzelne Ressourcen zu erstellen. Mache es Dir leicht und beginne mit kleinen, leicht definierten Ressourcen.
Berücksichtige die Verbundenheit
Eines der Prinzipien von REST ist die Verbindung. Während Dienste ohne sie immer noch nützlich sind, werden APIs selbstbeschreibender und auffindbarer, wenn Links in der Antwort zurückgegeben werden. Verwende zusätzlich den HTTP Location Header, um einen Link zur Ressourcenerstellung über POST (oder PUT) zu enthalten.