restAan de slag met rust


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.

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 geen content 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" }
    }
  }
 

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:

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

Redirection

Klantfouten

Serverfouten

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-veld If-None-Match / If-Match ; de voorwaarde in If-None-Match / If-Match wordt beschouwd als een meer accurate vervanging voor de voorwaarde in If-Modified-Since / If-Unmodified-Since , en de twee worden alleen gecombineerd omwille van de samenwerking met oudere tussenpersonen die mogelijk de functie If-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 de PUT 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" }
  ]
 
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:

  1. 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.

  2. 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 met DELETE /gists/:id/star .

  3. 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
                        ^^^^
 
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
                             ^^^^^^^^^^^^^^^^^^
 
  • HATEOAS biedt een " zelfkoppeling " naar bronnen, gericht op zichzelf:
{
  ...,
  _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" }
    ^^^^^^^^^
  }
}
 

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:

  1. Op bronnen gebaseerde locaties / URI
  2. Correct gebruik van HTTP-methoden
  3. 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.

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/ .