rest Zelfstudie
Aan de slag met rust
Zoeken…
Opmerkingen
Deze sectie geeft een overzicht van wat rust is en waarom een ontwikkelaar het misschien wil gebruiken.
Het moet ook alle grote onderwerpen in rust vermelden en een link naar de gerelateerde onderwerpen bevatten. Aangezien de documentatie voor rust nieuw is, moet u mogelijk eerste versies van die gerelateerde onderwerpen maken.
REST Overzicht
REST staat voor RE presentational S tate T ransfer en werd bedacht door Roy Fielding in zijn proefschrift Architectural Styles and the Design of Network-based Software Architectures . Daarin identificeert hij specifieke architecturale principes zoals:
Adresseerbare bronnen: de belangrijkste abstractie van informatie en gegevens in REST is een bron en elke bron moet adresseerbaar zijn via een URI.
Een uniforme, beperkte interface: gebruik van een kleine set goed gedefinieerde methoden om onze bronnen te manipuleren.
Representatiegericht: een bron waarnaar wordt verwezen door één URI kan verschillende indelingen hebben en verschillende platforms hebben verschillende indelingen nodig, bijvoorbeeld browsers hebben HTML nodig, JavaScript heeft JSON nodig en Java-toepassingen kunnen XML, JSON, CSV, tekst, enz. Nodig hebben. Dus we communiceren met services gebruik maken van representatie van die dienst.
Stateless communiceren: stateless applicaties zijn eenvoudiger te schalen.
Hypermedia As The Engine Of Application State: laat onze dataformaten de statusovergangen in onze applicaties aansturen.
De set van deze architecturale principes wordt REST genoemd. De concepten van REST zijn geïnspireerd op die van HTTP. Roy Fielding die REST aan ons gaf, is ook een van de auteurs van HTTP-specificaties.
Webservices en RESTful Web Services zijn services die worden blootgesteld aan internet voor programmatische toegang. Het zijn online api die we vanuit onze code kunnen bellen. Er zijn twee soorten SOAP- en REST-webservices “Big” .
RESTful Web Services : Webservices die zijn geschreven door toepassing van de REST-architecturale concepten worden RESTful Web Services genoemd, die zich richten op systeembronnen en hoe de status van een bron kan worden overgedragen via HTTP-protocol naar verschillende clients.
Dit document is uitsluitend gericht op RESTful-webservices, dus we zullen niet ingaan op de details van SOAP WS.
Er zijn geen strikte regels bij het ontwerpen van RESTful-webservices zoals
- Geen protocolstandaard
- Geen standaard communicatiekanaal
- Geen standaard voor servicedefinitie
Maar SOAP heeft strikte regels voor al deze. Alle SOAP-webservices volgen de SOAP-specificatie die bepaalt wat elke SOAP-webservice moet zijn. Deze specificatie is ontwikkeld en beheerd door een commissie en als SOAP WS zelfs geen enkele regel volgt, is het per definitie geen SOAP.
Concepten van RESTful Web Services
Er zijn enkele richtlijnen waarmee rekening moet worden gehouden bij het ontwerpen / ontwikkelen van RESTful api:
- Op bronnen gebaseerde locaties / URI
- Correct gebruik van HTTP-methoden
- HATEOAS (Hypermedia As The Engine Of Application State)
De belangrijkste aanpak bij het ontwikkelen van RESTful API's moet zijn om de API "zo RESTful mogelijk" te maken.
RUST via HTTP
REST is een protocol-agnostische architectuur voorgesteld door Roy Fielding in zijn proefschrift (hoofdstuk 5 is de presentatie van REST), die het bewezen concept van webbrowsers als clients generaliseert om clients in een gedistribueerd systeem van servers te ontkoppelen.
Om een service of API RESTful te laten zijn, moet deze voldoen aan gegeven beperkingen zoals:
- Client server
- stateless
- cacheable
- Gelaagd systeem
- Uniforme interface
- Bronnen identificatie
- Bronnen vertegenwoordiging
- Zelfbeschrijvende berichten
- hypermedia
Naast de beperkingen die in het proefschrift van Fielding worden genoemd, moet REST API's in zijn blogpost hypertekstgedreven zijn , en Fielding verduidelijkte dat alleen het oproepen van een service via HTTP het niet RESTful maakt . Een dienst moet daarom ook verdere regels respecteren die als volgt worden samengevat:
De API moet het onderliggende protocol naleven en niet schenden. Hoewel REST meestal via HTTP wordt gebruikt, is het niet beperkt tot dit protocol.
Sterke focus op middelen en hun presentatie via mediatypen.
Cliënten mogen geen initiële kennis of veronderstellingen hebben over de beschikbare bronnen of hun geretourneerde status ( "getypte" bron ) in een API, maar moeten ze onmiddellijk leren via verstrekte verzoeken en geanalyseerde antwoorden. Dit geeft de server de mogelijkheid om eenvoudig middelen te verplaatsen of te hernoemen zonder een clientimplementatie te verbreken.
Richardson Maturity Model
Het Richardson Maturity Model is een manier om REST-beperkingen toe te passen via HTTP om RESTful-webservices te verkrijgen.
Leonard Richardson verdeelde toepassingen in deze 4 lagen:
- Niveau 0: gebruik van HTTP voor het transport
- Niveau 1: gebruik van URL om bronnen te identificeren
- Niveau 2: gebruik van HTTP-werkwoorden en statussen voor de interacties
- Niveau 3: gebruik van HATEOAS
Omdat de nadruk ligt op de weergave van de status van een resource, wordt het ondersteunen van meerdere representaties voor dezelfde resource aangemoedigd. Een weergave zou daarom een overzicht van de bronstatus kunnen geven, terwijl een andere de volledige details van dezelfde bron retourneert.
Merk ook op dat, gezien de beperkingen van Fielding, een API pas effectief RESTful is als het 3e niveau van de RMM is geïmplementeerd .
HTTP-verzoeken en antwoorden
Een HTTP-verzoek is:
- Een werkwoord (ook wel methode genoemd), meestal GET , POST , PUT , DELETE of PATCH
- Een URL
- Headers (sleutel / waarde-paren)
- Optioneel een body (aka payload, data)
Een HTTP-reactie is:
- Een status, meestal een van 2xx (succesvol) , 4xx (clientfout) of 5xx (serverfout)
- Headers (sleutel / waarde-paren)
- Een body (aka payload, data)
HTTP werkwoorden kenmerken:
- Werkwoorden met een lichaam:
POST
,PUT
,PATCH
- Werkwoorden die veilig moeten zijn (dat wil zeggen geen bronnen mogen wijzigen):
GET
- Werkwoorden die idempotent moeten zijn (dat wil zeggen dat ze geen invloed mogen hebben op bronnen wanneer ze meerdere keren worden uitgevoerd):
GET
(nullipotent),PUT
,DELETE
body safe idempotent
GET ✗ ✔ ✔
POST ✔ ✗ ✗
PUT ✔ ✗ ✔
DELETE ✗ ✗ ✔
PATCH ✔ ✗ ✗
Daarom kunnen HTTP-werkwoorden worden vergeleken met de CRUD-functies :
Merk op dat een PUT
verzoek clients vraagt om de volledige bron met de bijgewerkte waarden te verzenden . Om een resource gedeeltelijk bij te werken, kan een werkwoord PATCH
worden gebruikt (zie Hoe een resource gedeeltelijk bij te werken? ).
Gebruikelijke HTTP-antwoordstatussen
Succes
- 201 (CREATED) : resource is aangemaakt
- 202 (AANVAARD) : verzoek geaccepteerd, maar het proces is nog bezig
- 204 (GEEN INHOUD) : verzoek ingewilligd en geen aanvullende inhoud
- Anders: 200 (OK)
Redirection
- 304 (NIET GEMODIFICEERD) : client kan de gecachte versie van de gevraagde bron gebruiken
Klantfouten
- 401 (ONGEAUTORISEERD) : een anoniem verzoek geeft toegang tot een beschermde API
- 403 (VERBODEN) : een geverifieerd verzoek heeft onvoldoende rechten om toegang te krijgen tot een beschermde API
- 404 (NIET GEVONDEN) : bron niet gevonden
- 409 (CONFLICT) : bronstatus in conflict (bijv. Een gebruiker die een account probeert aan te maken met een al geregistreerde e-mail)
- 410 (GONE) : hetzelfde als 404, maar de bron bestond
- 412 (PRECONDITION FAILED) : aanvraag probeert een bron te wijzigen die zich in een onverwachte status bevindt
- 422 (ONBESPARENDE ENTITEIT) : aanvraagbelasting is syntactisch geldig, maar semantisch onjuist (bijv. Een verplicht veld dat niet is gewaardeerd)
- 423 (LOCKED) : bron is vergrendeld
- 424 (FAILED DEPENDENCY) : gevraagde actie hing af van een andere actie die is mislukt
- 429 (TE VEEL AANVRAGEN) : gebruiker heeft te veel aanvragen binnen een bepaalde tijd verzonden
- Anders: 400 (SLECHT VERZOEK)
Serverfouten
- 501 (NIET UITGEVOERD) : server ondersteunt niet de functionaliteit die vereist is om aan het verzoek te voldoen
- 503 (SERVICE NIET BESCHIKBAAR) : server kan het verzoek momenteel niet verwerken vanwege een tijdelijke overbelasting of gepland onderhoud
- 507 (ONVOLDOENDE OPSLAG) : server kan de representatie niet opslaan die nodig is om het verzoek te voltooien
- Anders: 500 (INTERNE SERVERFOUT)
Notes
Niets weerhoudt u van het toevoegen van een body aan foute reacties, om de afwijzing duidelijker te maken voor klanten. De 422 (ONBESPARENDE ENTITEIT) is bijvoorbeeld een beetje vaag: responsinstantie moet de reden geven waarom de entiteit niet kan worden verwerkt.
HATEOAS
Elke bron moet hypermedia bieden aan de bronnen waaraan deze is gekoppeld. Een link is minimaal samengesteld door:
- Een
rel
(voor relatie , ook bekend als naam): beschrijft de relatie tussen de hoofdbron en de gekoppelde bron (nen) - A
href
: de URL gericht op de gelinkte bron (nen)
Aanvullende attributen kunnen ook worden gebruikt om te helpen met afschrijving, onderhandeling over inhoud, enz.
Cormac Mulhall legt uit dat de client moet beslissen welk HTTP-werkwoord moet worden gebruikt op basis van wat het probeert te doen . Bij twijfel zou de API-documentatie u hoe dan ook moeten helpen de beschikbare interacties met alle hypermedia te begrijpen.
Mediatypen
Mediatypen helpen met zelfbeschrijvende berichten. Ze spelen de rol van het contract tussen clients en servers, zodat ze middelen en hypermedieën kunnen uitwisselen.
Hoewel application/json
en application/xml
vrij populaire mediatypen zijn, bevatten ze niet veel semantiek. Ze beschrijven alleen de algemene syntaxis die in het document wordt gebruikt. Meer gespecialiseerde mediatypen die de HATEOAS-vereisten ondersteunen, moeten worden gebruikt (of uitgebreid via mediatypen van leveranciers ), zoals:
Een client vertelt een server welke mediatypen hij begrijpt door de Accept
header aan zijn verzoek toe te voegen, bijvoorbeeld:
Accept: application/hal+json
Als de server de gevraagde bron niet in een dergelijke weergave kan produceren, retourneert deze een 406 (NIET AANVAARDBAAR) . Anders wordt het mediatype toegevoegd in de kop Content-Type
van het antwoord dat de weergegeven bron bevat, bijvoorbeeld:
Content-Type: application/hal+json
Staatloos> stateful
Waarom?
Een stateful server houdt in dat de clientsessies worden opgeslagen in een server-instantie-lokale opslag (bijna altijd in webserversessies). Dit begint een probleem te zijn wanneer u horizontaal probeert te schalen : als u verschillende serverinstanties achter een taakverdeler verbergt, als een client eerst naar exemplaar # 1 wordt verzonden bij het aanmelden, maar daarna naar exemplaar # 2 bij het ophalen van een beschermde bron, bijvoorbeeld , zal het tweede exemplaar het verzoek als anoniem behandelen, omdat de clientsessie lokaal is opgeslagen in exemplaar # 1 .
Er zijn oplossingen gevonden om dit probleem aan te pakken (bijvoorbeeld door sessiereplicatie en / of plakkerige sessie te configureren), maar de REST-architectuur stelt een andere aanpak voor: maak uw server niet stateful, maak deze stateless . Volgens Fielding :
Elk verzoek van client naar server moet alle informatie bevatten die nodig is om het verzoek te begrijpen, en kan geen voordeel halen uit een opgeslagen context op de server. De sessiestatus wordt daarom volledig bij de cliënt bewaard.
Met andere woorden, een verzoek moet op precies dezelfde manier worden afgehandeld, ongeacht of het wordt verzonden naar exemplaar # 1 of exemplaar # 2 . Dit is de reden waarom staatloze toepassingen als gemakkelijker te schalen worden beschouwd.
Hoe?
Een veel voorkomende aanpak is een token-gebaseerde authenticatie , vooral met de trendy JSON Web Tokens . Merk echter op dat JWT nog steeds enkele problemen heeft, met name met betrekking tot ongeldigheid en automatische verlenging van de vervaldatum (dwz de functie Onthoud mij ).
Side notes
Het gebruik van cookies of headers (of iets anders) heeft niets te maken met het feit of de server stateful of stateless is: dit zijn alleen media die hier worden gebruikt om tokens te transporteren (sessie-ID voor stateful servers, JWT, etc.), niets meer.
Wanneer een RESTful API alleen door browsers wordt gebruikt, kunnen cookies ( HttpOnly en veilig ) heel handig zijn, omdat browsers ze automatisch aan uitgaande verzoeken koppelen. Het is vermeldenswaard dat als u voor cookies kiest, u rekening moet houden met CSRF (een leuke manier om te voorkomen dat de clients dezelfde unieke geheime waarde genereren en verzenden in zowel een cookie als een aangepaste HTTP-header ).
Cacheable API met voorwaardelijke verzoeken
Met de kop Last-Modified
De server kan een Last-Modified
datumkop geven aan de antwoorden met bronnen die kunnen worden opgeslagen. Klanten moeten deze datum vervolgens samen met de resource opslaan.
Nu kunnen clients telkens wanneer ze de API vragen om de resource te lezen, een If-Modified-Since
header toevoegen met de laatste Last-Modified
datum die ze hebben ontvangen en opgeslagen. De server moet vervolgens de koptekst van het verzoek en de werkelijke laatst gewijzigde datum van de bron vergelijken. Als ze gelijk zijn, retourneert de server een 304 (NIET GEMODIFICEERD) met een lege body: de aanvragende client moet de bron in de cache gebruiken die hij heeft.
Wanneer clients de API vragen om de bron bij te werken (dwz met een onveilig werkwoord), kunnen ze ook een If-Unmodified-Since
header toevoegen . Dit helpt om te gaan met racecondities: als de koptekst en de werkelijke laatst gewijzigde datum verschillen, retourneert de server een 412 (PRECONDITION FAILED) . De client moet vervolgens de nieuwe status van de bron lezen voordat hij de bron opnieuw probeert te wijzigen.
Met de header ETag
Een ETag (entiteitstag) is een ID voor een specifieke status van een resource. Het kan een MD5-hash van de bron zijn voor een sterke validatie of een domeinspecifieke id voor een zwakke validatie .
Kortom, het proces is hetzelfde als bij de Last-Modified
header: de server biedt een ETag
header aan de antwoorden met bronnen die cacheerbaar zijn, en clients moeten deze identifier vervolgens samen met de resource opslaan.
Vervolgens geven clients een header If-None-Match
wanneer ze de bron willen lezen, met de nieuwste ETag die ze hebben ontvangen en opgeslagen. De server kan nu een 304 (NIET GEWIJZIGD) retourneren als de header overeenkomt met de werkelijke ETag van de resource.
Nogmaals, clients kunnen een If-Match
header opgeven wanneer ze de resource willen wijzigen en de server moet een 412 (PRECONDITION FAILED) retourneren als de verstrekte ETag niet overeenkomt met de werkelijke.
Extra notities
ETag> datum
Als klanten zowel datum als ETag in hun verzoek vermelden, moet de datum worden genegeerd. Van RFC 7232 ( hier en hier ):
Een ontvanger MOET
If-Modified-Since
/If-Unmodified-Since
negeren als het verzoek een header-veldIf-None-Match
/If-Match
; de voorwaarde inIf-None-Match
/If-Match
wordt beschouwd als een meer accurate vervanging voor de voorwaarde inIf-Modified-Since
/If-Unmodified-Since
, en de twee worden alleen gecombineerd omwille van de samenwerking met oudere tussenpersonen die mogelijk de functieIf-None-Match
/If-Match
niet implementeert.
Ondiepe ETags
Hoewel het vrij duidelijk is dat de laatste gewijzigde datums samen met de serverzijde blijven bestaan, zijn er verschillende benaderingen beschikbaar met ETag.
Een gebruikelijke aanpak is om ondiepe ETags te implementeren: de server verwerkt het verzoek alsof er geen voorwaardelijke headers zijn gegeven, maar aan het einde genereert het de ETag van de reactie die het gaat retourneren (bijvoorbeeld door het te hashen) en vergelijkt het het met de meegeleverde. Dit is relatief eenvoudig te implementeren omdat alleen een HTTP-interceptor nodig is (en er bestaan al veel implementaties, afhankelijk van de server). Dat gezegd hebbende, is het vermeldenswaard dat deze aanpak bandbreedte bespaart, maar geen serverprestaties :
Een diepere implementatie van het ETag-mechanisme zou potentieel veel grotere voordelen kunnen bieden - zoals het bedienen van sommige aanvragen uit de cache en het helemaal niet hoeven uitvoeren van de berekening - maar de implementatie zou zeker niet zo eenvoudig zijn, noch zo pluggable als de oppervlakkige aanpak hier beschreven.
Veel voorkomende valkuilen
Waarom zou ik geen werkwoorden in URL's plaatsen?
HTTP is geen RPC : wat HTTP aanzienlijk anders maakt dan RPC is dat de verzoeken naar bronnen worden gericht . URL staat immers voor Uniform Resource Locator en een URL is een URI : een Uniform Resource Idenfitier. De URL richt zich op de bron waarmee u wilt werken , de HTTP-methode geeft aan wat u ermee wilt doen . HTTP-methoden worden ook wel werkwoorden genoemd : werkwoorden in URL's hebben geen zin. Merk op dat HATEOAS-relaties ook geen werkwoorden mogen bevatten, omdat koppelingen ook op bronnen zijn gericht.
Hoe een resource gedeeltelijk bij te werken?
Omdat PUT
aanvragen clients vragen de volledige bron met de bijgewerkte waarden te verzenden, kan PUT /users/123
niet worden gebruikt om bijvoorbeeld de e-mail van een gebruiker eenvoudig bij te werken. Zoals uitgelegd door William Durand in Please. Niet patchen als een idioot. , verschillende REST-compatibele oplossingen zijn beschikbaar:
- Leg de eigenschappen van de resource bloot en gebruik de
PUT
methode om een bijgewerkte waarde te verzenden, omdat dePUT
specificatie aangeeft dat gedeeltelijke inhoudupdates mogelijk zijn door een afzonderlijk geïdentificeerde resource te richten met de status die een deel van de grotere resource overlapt :
PUT https://example.com/api/v1.2/users/123/email
body:
new.email@example.com
- Gebruik een
PATCH
verzoek dat een set instructies bevat die beschrijven hoe de resource moet worden gewijzigd (bijvoorbeeld na de JSON-patch ):
PATCH https://example.com/api/v1.2/users/123
body:
[
{ "op": "replace", "path": "/email", "value": "new.email@example.com" }
]
- Gebruik een
PATCH
verzoek met een gedeeltelijke weergave van de resource, zoals voorgesteld in de opmerking van Matt Chapman :
PATCH https://example.com/api/v1.2/users/123
body:
{
"email": "new.email@example.com"
}
Hoe zit het met acties die niet passen in de wereld van CRUD-operaties?
Citeren van Vinay Sahni in Best Practices voor het ontwerpen van een Pragmatische RESTful API :
Hier kunnen dingen wazig worden. Er zijn een aantal benaderingen:
Herstructureer de actie zodat deze eruit ziet als een veld van een resource. Dit werkt als de actie geen parameters aanneemt. Een activeringsactie kan bijvoorbeeld worden toegewezen aan een boolean
activated
veld en via een PATCH worden bijgewerkt naar de resource.Behandel het als een hulpbron met RESTful principes. Met de API van GitHub kunt u bijvoorbeeld een gist een ster geven met
PUT /gists/:id/star
en een ster metDELETE /gists/:id/star
.Soms heb je echt geen manier om de actie in een verstandige RESTful-structuur te brengen. Een zoekopdracht met meerdere bronnen heeft bijvoorbeeld geen zin om te worden toegepast op het eindpunt van een specifieke bron. In dit geval zou
/search
het meest logisch zijn, hoewel het geen bron is. Dit is OK - doe gewoon wat goed is vanuit het perspectief van de API-consument en zorg ervoor dat het duidelijk is gedocumenteerd om verwarring te voorkomen.
Gemeenschappelijke praktijken
API is gedocumenteerd. Er zijn hulpmiddelen beschikbaar om u te helpen bij het samenstellen van uw documentatie, bijvoorbeeld Swagger of Spring REST Docs .
API is versiebeheer , hetzij via headers of via de URL:
https://example.com/api/v1.2/blogs/123/articles
^^^^
- Bronnen hebben meerdere namen :
https://example.com/api/v1.2/blogs/123/articles
^^^^^ ^^^^^^^^
- URL's gebruiken kebab-hoofdletters (woorden worden in kleine letters geplaatst en gescheiden door streepjes):
https://example.com/api/v1.2/quotation-requests
^^^^^^^^^^^^^^^^^^
{
...,
_links: {
...,
self: { href: "https://example.com/api/v1.2/blogs/123/articles/789" }
^^^^
}
}
- HATEOAS-relaties gebruiken lowerCamelCase (woorden worden in kleine letters geplaatst, vervolgens in hoofdletters behalve de eerste, en spaties worden weggelaten), zodat JavaScript-clients de puntnotatie kunnen gebruiken met inachtneming van de JavaScript-naamgevingsconventies bij het openen van de links:
{
...,
_links: {
...,
firstPage: { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" }
^^^^^^^^^
}
}
Blogsbeheer via een RESTful HTTP API
De volgende voorbeelden gebruiken HAL om HATEOAS uit te drukken en maken gebruik van:
- CURIE (Compact URI): wordt gebruikt om links naar API-documentatie te bieden
- URI-sjablonen : URI die parameters bevat die moeten worden vervangen voordat de URI wordt opgelost
Download blog 123
Verzoek
GET https://example.com/api/v1.2/blogs/123
headers:
Accept: application/hal+json
antwoord
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 123,
"title": "The blog title",
"description": "The blog description",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123" },
"doc:articles": { "href": "https://example.com/api/v1.2/blogs/123/articles{?pageIndex,pageSize}", "templated": true }
}
}
Maak een nieuw artikel in blog 123
Verzoek
POST https://example.com/api/v1.2/blogs/123/articles
headers:
Content-Type: application/json
Accept: application/hal+json
X-Access-Token: XYZ
body:
{
"title": "The title 2",
"content": "The content 2"
}
antwoord
status: 201 (CREATED)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Ontvang artikel 789 van blog 123
Verzoek
GET https://example.com/api/v1.2/blogs/123/articles/789
headers:
Accept: application/hal+json
antwoord
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Ontvang de 4e pagina van 25 artikelen van blog 123
Verzoek
GET https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25
headers:
Accept: application/hal+json
antwoord
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"pageIndex": 4,
"pageSize": 25,
"totalPages": 26,
"totalArticles": 648,
"_link": {
"firstPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" },
"previousPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=3&pageSize=25" },
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25" },
"nextPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=5&pageSize=25" },
"lastPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=26&pageSize=25" }
},
"_embedded": [
{
...
}, {
"id": 456,
"title": "The title 1",
"content": "The content 1",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/456" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/456/comments{?pageIndex,pageSize}", "templated": true }
}
}, {
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}, {
...
}
]
}
Update artikel 789 van blog 123
Verzoek
PUT https://example.com/api/v1.2/blogs/123/articles/789
headers:
Content-Type: application/json
Accept: application/hal+json
X-Access-Token: XYZ
body:
{
"id": 789,
"title": "The title 2 updated",
"content": "The content 2 updated"
}
antwoord
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2 updated",
"content": "The content 2 updated",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Notes
- De identificatie die wordt gebruikt om de bij te werken bron te identificeren, is die in de URL : die in de body (indien aanwezig) moet zwijgend worden genegeerd.
- Als een
PUT
verzoek de hele bron bijwerkt, zou, als er geencontent
zou zijn verzonden, deze uit de aanhoudende bron moeten zijn verwijderd.
Verwijder artikel 789 van blog 123
Verzoek
DELETE https://example.com/api/v1.2/blogs/123/articles/789
headers:
Accept: application/hal+json
X-Access-Token: XYZ
antwoord
status: 204 (NO CONTENT)
headers:
Content-Type: application/hal+json
body:
{
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" }
}
}
REST overtreden
<stock>
<add>
<item>
<name>Milk</name>
<quantity>2</quantity>
</item>
</add>
</stock>
Het plaatsen van dit lichaam in een bron zoals /stocks/123
strijd met het idee achter REST. Hoewel dit lichaam is put
en het alle benodigde informatie bevat, komt het ook met een methodeaanroep add
ergens add
te add
wanneer het lichaam wordt verwerkt. Na REST zou men het item
posten naar /stocks/123/items/
.