Kursinhalt
Spring Boot Backend
Spring Boot Backend
Grundprinzipien von REST
Die Kernprinzipien von REST bilden die Grundlage für die Erstellung effektiver und leicht skalierbarer Webdienste. In Spring Boot werden sie häufig zur Implementierung von APIs verwendet.
Lassen Sie uns erkunden, was diese Prinzipien sind, warum sie wichtig sind und Beispiele für ihre Anwendung in Spring Boot untersuchen.
Kernprinzipien von REST
REST (Representational State Transfer) ist ein Architekturstil, der auf sechs Schlüsselprinzipien basiert, die Entwicklern helfen, einfache, flexible und skalierbare APIs zu erstellen. Diese Prinzipien beschreiben, wie Systeme interagieren sollten, um anpassungsfähig und wartbar zu bleiben.
Client-Server-Architektur
Eine REST-API sollte die Verantwortlichkeiten zwischen dem Client und dem Server trennen. Der Client ist verantwortlich für die Benutzeroberfläche und das Stellen von Anfragen, während der Server die Datenspeicherung und die Anfrageverarbeitung übernimmt.
Die REST-API sorgt für eine klare Trennung zwischen der Client-Seite und der Server-Seite der Anwendung, sodass sie sich unabhängig entwickeln können.
Die Client-Seite könnte ein Webbrowser, eine Mobile App oder eine andere Client-Anwendung sein, während die Server-Seite in jeder Programmiersprache implementiert werden kann.
Zustandslos
Jede Anfrage vom Client an den Server muss alle Informationen enthalten, die zur Verarbeitung dieser Anfrage benötigt werden. Der Server sollte keinen Zustand zwischen den Anfragen beibehalten, um sicherzustellen, dass jede Anfrage isoliert von anderen ist.
Zum Beispiel, stellen wir uns vor, wir haben eine Anwendung, die eine Liste von Produkten in verschiedenen Sprachen zurückgibt. Der Client muss die Sprachinformation in jeder Anfrage einschließen, damit der Server weiß, welche Sprache er für die Antwort verwenden soll. Der Server speichert keine Sprachinformationen zwischen den Anfragen. Lassen Sie uns dieses Beispiel in Code implementieren.
Main
@RestController @RequestMapping("/products") public class ProductController { @GetMapping public List<Product> getProducts(@RequestParam("lang") String language) { // Check the language requested by the client if ("en".equals(language)) { return productService.getProductsInEnglish(); } else if ("es".equals(language)) { return productService.getProductsInSpanish(); } else { return productService.getProductsInDefaultLanguage(); } } }
Dieser Code repräsentiert einen REST-Controller, der HTTP-GET
-Anfragen am Endpunkt /products
bearbeitet. Die Methode getProducts()
nimmt einen lang
-Parameter entgegen, der die Sprache angibt, in der der Client die Daten empfangen möchte.
Basierend auf diesem Parameter gibt die Methode eine Liste von Produkten in der angegebenen Sprache oder in der Standardsprache zurück.
Einheitliche Schnittstelle
Um eine REST-API einfach nutzbar zu machen, sollte sie eine einfache und organisierte Struktur haben. Das bedeutet, dass alle Endpunkte einigen grundlegenden Richtlinien folgen müssen. Hier sind die Schlüsselprinzipien:
Verwenden Sie Substantive, um Ressourcen zu repräsentieren, anstatt Verben. Zum Beispiel ist es besser, POST /createProduct
zu verwenden, anstatt GET /products
, wobei products die Ressource ist.
GET /products
— Ruft eine Liste von Produkten ab;
POST /products
— Erstellt ein neues Produkt;
PUT /products/{id}
— Aktualisiert Informationen über ein bestimmtes Produkt, wobei {id}
der eindeutige Bezeichner des Produkts ist;
DELETE /products/{id}
— Löscht das Produkt mit dem angegebenen Bezeichner.
Lassen Sie uns einen Spring REST-Controller beschreiben, der Produkte verwaltet, indem er verschiedene HTTP-Methoden für das Erstellen, Abrufen, Aktualisieren und Löschen von Produktdaten implementiert und dabei Best Practices für eine benutzerfreundliche API-Struktur befolgt.
Main
@RestController @RequestMapping("/products") public class ProductController { // Example of applying the client-server architecture principle private final ProductService productService; // Constructor injection ensures productService is provided by Spring public ProductController(ProductService productService) { this.productService = productService; } // Uniform interface principle: GET request to retrieve all products @GetMapping public List<Product> getAllProducts() { // Calls the service to return a list of all products return productService.getAllProducts(); } // Uniform interface principle: POST request to create a new product @PostMapping public Product createProduct(@RequestBody Product product) { // Calls the service to create a new product based on the provided request body return productService.createProduct(product); } // Uniform interface principle: GET request to retrieve a product by its ID @GetMapping("/{id}") public Product getProductById(@PathVariable Long id) { // Calls the service to find and return the product with the given ID return productService.getProductById(id); } // Uniform interface principle: PUT request to update a product by its ID @PutMapping("/{id}") public Product updateProduct(@PathVariable Long id, @RequestBody Product product) { // Calls the service to update the product details based on the provided request body and ID return productService.updateProduct(id, product); } // Uniform interface principle: DELETE request to remove a product by its ID @DeleteMapping("/{id}") public void deleteProduct(@PathVariable Long id) { // Calls the service to delete the product with the specified ID productService.deleteProduct(id); } }
Die @RequestMapping("/products")
Annotation gibt an, dass die Basis-URL /products
automatisch vorangestellt wird zu allen Routen innerhalb dieses Controllers.
In diesem Beispiel behandelt der Controller Operationen, die sich auf die Product
-Entität (Product-Klasse) beziehen, daher ist die Basis-URL /products
. Dieser Ansatz vermeidet die Wiederholung von /products
für jede Methode. Stattdessen geben wir einfach die HTTP-Methoden (GET, POST, PUT, DELETE) an, die auf diese Basis-URL angewendet werden.
GET /products
— Ruft eine Liste von Produkten ab;
POST /products
— Erstellt ein neues Produkt.
Wir können mehrere Endpunkte mit derselben URL, aber unterschiedlichen HTTP-Methoden haben. Zum Beispiel teilen sich GET /products
und POST /products
dieselbe URL, verwenden jedoch unterschiedliche HTTP-Methoden. Der Client gibt die HTTP-Methode im Request-Header an, um anzuzeigen, welche Aktion ausgeführt werden soll.
Caching
Um die Leistung zu verbessern, kann der Server dem Client anweisen, wann Daten zwischengespeichert werden sollen. Dies reduziert die Serverlast und beschleunigt die Anfragenverarbeitung.
Das bedeutet, dass wenn die Methode mit den gleichen Parametern aufgerufen wird, das Ergebnis aus dem Cache abgerufen wird, anstatt die Methode erneut auszuführen. Dies kann die Leistung verbessern, indem die Belastung des Dienstes reduziert wird.
In Spring Boot kann das Caching von Antworten mithilfe von Annotationen oder HTTP-Headern verwaltet werden. Hier ist ein Beispiel für Daten-Caching:
Main
@Cacheable("products") @GetMapping public List<Product> getAllProducts() { return productService.getAllProducts(); }
In diesem Beispiel wird die @Cacheable
Annotation verwendet, um das Ergebnis der getAllProducts()
Methode zu cachen.
Die @Cacheable("products")
Annotation gibt an, dass das Ergebnis der getAllProducts()
Methode im Cache unter dem Namen products
gespeichert wird. Wenn die Methode mit den gleichen Parametern erneut aufgerufen wird, sucht Spring das Ergebnis im products
Cache, anstatt die Methode erneut auszuführen.
Schichtsystem
Das Schichtsystem-Prinzip in REST API bedeutet, dass der Client nicht nur mit einem Server interagiert; stattdessen arbeitet er durch mehrere Ebenen. Lassen Sie uns dies anhand der Drei-Schichten-Architektur in Spring Boot erklären.
Wenn der Client eine Anfrage sendet, durchläuft sie alle drei Ebenen: vom Controller zum Service, dann zum Repository und zurück. Diese Trennung hilft, das System organisiert zu halten und macht es einfacher, den Code zu warten.
Code on Demand
Obwohl weniger häufig verwendet, kann eine REST API ausführbaren Code an den Client zurückgeben, der auf deren Seite ausgeführt wird. Dieses Prinzip wird selten angewendet und erfordert zusätzliche Sicherheitsmaßnahmen.
Zum Beispiel könnte eine API JavaScript-Code zurückgeben, der im Browser des Clients ausgeführt wird, um Daten zu verarbeiten oder andere Aufgaben zu erledigen. Dies kann nützlich sein, um dynamisch Funktionalitäten basierend auf Anfragen zu laden, wie z.B. Formularbearbeitung oder clientseitige Datenvalidierung.
Zusammenfassung
Die grundlegenden Prinzipien von REST sind wesentliche Richtlinien für die Erstellung flexibler und wartbarer APIs. In Spring Boot werden diese Prinzipien mit Annotationen wie @RestController
, @Cacheable
implementiert, die die Entwicklung von gut strukturierten und effizienten Systemen zur Interaktion mit Clients erleichtern.
1. Welches REST
-Prinzip ermöglicht es dem Client, mit einer Ressource unter Verwendung standardmäßiger HTTP
-Methoden zu interagieren?
2. Was bedeutet das zustandslose Prinzip in REST
?
Danke für Ihr Feedback!