📜 ⬆️ ⬇️

Is your service RESTful? All you need / need to know about web services and REST

Introduction


I don’t like to reinvent the wheel and I wouldn’t write this article, but I had to. About REST has already been said quite a lot. Many web service providers are ready to swear that their services are RESTful. During the interview, you will definitely hear at least a few questions about REST, regardless of whether it is an interview for a backend, mobile or developer frontend. I remember once during one interview I was asked this question: “You wrote in your resume that you know REST Please answer, what HTTP code will you get if the resource is not found when you request a RESTful service? ”. Answer 404 was adopted unanimously. To be honest, I still didn’t understand how this question helped me to understand whether I know REST or not, but one thing I can confidently say is that not everyone understands REST. Here are some questions that tormented me for a long time:

  1. Why did REST become so trendy? Was this architecture proposed in 2000?
  2. What will I get if my service is RESTful?
  3. How to determine if a service is RESTful or not?
  4. How should the service REST URLs be created correctly?
  5. What http methods and codes should be used in the RESTful service?

If you cannot give an exhaustive answer to at least one of these questions, then continue reading. If you can answer all these questions unequivocally, give the format of the correct URL, consider that GET, POST, PUT, DELETE must correspond to CRUD operations with resources, then you should definitely continue reading.

To find the answers to these questions and present the overall picture, I had to read a bunch of specifications, Roy Fielding’s thesis and Leonard Richardson’s book, as it turned out that there was a lot of confusion on the Internet and in particular in Stack Overflow. The found information seemed to me quite useful, so I decided to share it with you.

Since we consider REST from the point of view of web services, in the article I tried to explain everything that needs to be known in order to present the big picture.
')
Well, let's start the journey into the world of web services.

SOA & Web Services


SOA , expandable as a service oriented architecture (Service Oriented Architecture), is a paradigm for the organization and use of distributed systems that can be controlled by different areas of ownership [1]. In SOA, service means functionality that meets the following criteria [2]

  1. It is a functionality with a specific result.
  2. It is self-contained.
  3. It is a black box for customers.
  4. May consist of other services.

The Service Description is the service information needed to interact with the service (eg WSDL).
A Service Provider is people or organizations that provide services.
Service Consumer are customers, service consumers.

The Web Service , according to the definition [3], is a system designed for machine / program interaction over the network. The web service must have an interface described in the service description format. Other systems must interact with the web service through messages.

The relationship between a web service and SOA is that SOA can be implemented through web services.

If you are interested in what other methods exist or existed for the implementation of SOA, you can see COM and CORBA.

Web services protocols


Before deciding which service is RESTful, and which is not, consider some implementations, or otherwise they are called, web services protocols. A list of well-known protocols for web services can be found in [4].

1. XML RPC

The XML-RPC protocol (XML Remote Procedure Call) [5] was first published in 1999. All XML-RPC messages are HTTP-POST requests. XML is used to encode messages. Procedure parameters can be scalar values, numbers, strings, dates, arrays and structures. The web service response can store either the value returned by the procedure, or an error code and message.

An example of a request and response (an example is given from the specification itself [5]):
Host: betty.userland.com Content-Type: text/xml Content-length: 181 <?xml version="1.0"?> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>41</i4></value> </param> </params> </methodCall> 

 HTTP/1.1 200 OK Connection: close Content-Length: 158 Content-Type: text/xml Date: Fri, 17 Jul 1998 19:55:08 GMT Server: UserLand Frontier/5.1.2-WinNT <?xml version="1.0"?> <methodResponse> <params> <param> <value><string>South Dakota</string></value> </param> </params> </methodResponse> 


As a disadvantage of the XML-RPC protocol, there is a large message size (4 times more than conventional XML) and the non-existence of a web service description language (something like WSDL) that could be used to generate proxy classes on client side.

2. JSON-RPC

The JSON-RPC protocol [6], published in 2009, is very similar in its principles of operation to XML-RPC. The main differences are the method of data coding, the independence of the transport layer, the ability to send notifications (notification request) and the ability to identify responses when sending multiple requests at the same time.

JSON is used to encode data in JSON-RPC. In addition to the name of the procedure and parameters, the request also indicates the value of id, which is used to identify the response on the client. In other words, if you sent a request with id = 12345, then the response of this request must return a message with id = 12345.

Notifications are special requests that the server may not respond to. To mark a request as a notification, the value of the id parameter is indicated = null.

Independence from the transport layer can be determined only by the fact that the JSON-RPC [6] specification does not specify HTTP as a mandatory protocol. When using JSON-RPC over HTTP, you must use POST requests.

Example JSON-RPC request and response:
 --> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} <-- {"jsonrpc": "2.0", "result": 19, "id": 1} --> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3} <-- {"jsonrpc": "2.0", "result": 19, "id": 3} 


The disadvantage of JSON-RPC, as in the case of XML-RPC, is the lack of a web service description language (similar to WSDL).

3. SOAP

The Simple Object Access Protocol (SOAP) [7] is a descendant of XML-RPC. The main characteristics of SOAP are:

  1. All transmitted messages are encoded using XML (SOAP messages).
  2. All SOAP services have a WSDL description, which is also XML. This allows the client to automatically generate proxy classes.
  3. SOAP supports almost all known TCP / IP protocols (TCP, UDP, HTTP, SMTP, FTP, etc.). For this reason, SOAP is a rather complex protocol compared to the previous ones.
  4. When using HTTP, both the GET and POST methods are supported. GET is allowed only for data acquisition, i.e. on the server side, nothing should change. POST can be used for all cases. In practice, only POST is usually used.

The main disadvantage of SOAP is its complexity due to its flexibility. Another important disadvantage is the support for encoding only in XML.

Sample SOAP request and response:
HTTP GET:
 GET /travelcompany.example.org/reservations?code=FT35ZBQ HTTP/1.1 Host: travelcompany.example.org Accept: text/html;q=0.5, application/soap+xml 

 HTTP/1.1 200 OK Content-Type: application/soap+xml; charset="utf-8" Content-Length: nnnn <?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <m:reservation xmlns:m="http://travelcompany.example.org/reservation" env:role="http://www.w3.org/2003/05/soap-envelope/role/next" env:mustUnderstand="true"> <m:reference>uuid:093a2da1-q345-739r-ba5d-pqff98fe8j7d</m:reference> <m:dateAndTime>2001-11-30T16:25:00.000-05:00</m:dateAndTime> </m:reservation> </env:Header> <env:Body> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:x="http://travelcompany.example.org/vocab#" env:encodingStyle="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <x:ReservationRequest rdf:about="http://travelcompany.example.org/reservations?code=FT35ZBQ"> <x:passenger>Åke Jógvan Øyvind</x:passenger> <x:outbound> <x:TravelRequest> <x:to>LAX</x:to> <x:from>LGA</x:from> <x:date>2001-12-14</x:date> </x:TravelRequest> </x:outbound> <x:return> <x:TravelRequest> <x:to>JFK</x:to> <x:from>LAX</x:from> <x:date>2001-12-20</x:date> </x:TravelRequest> </x:return> </x:ReservationRequest> </rdf:RDF> </env:Body> </env:Envelope> 

HTTP POST:
 POST /Reservations HTTP/1.1 Host: travelcompany.example.org Content-Type: application/soap+xml; charset="utf-8" Content-Length: nnnn <?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" > <env:Header> <t:transaction xmlns:t="http://thirdparty.example.org/transaction" env:encodingStyle="http://example.com/encoding" env:mustUnderstand="true" >5</t:transaction> </env:Header> <env:Body> <m:chargeReservation env:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:m="http://travelcompany.example.org/"> <m:reservation xmlns:m="http://travelcompany.example.org/reservation"> <m:code>FT35ZBQ</m:code> </m:reservation> <o:creditCard xmlns:o="http://mycompany.example.com/financial"> <n:name xmlns:n="http://mycompany.example.com/employees"> Åke Jógvan Øyvind </n:name> <o:number>123456789099999</o:number> <o:expiration>2005-02</o:expiration> </o:creditCard> </m:chargeReservation </env:Body> </env:Envelope> 

 HTTP/1.1 200 OK Content-Type: application/soap+xml; charset="utf-8" Content-Length: nnnn <?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" > <env:Header> ... ... </env:Header> <env:Body> ... ... </env:Body> </env:Envelope> 


REST


REST is by far probably the most popular web service protocol .

In fact, REST is not a protocol at all and it is not new at all. REST is an architecture that was proposed in the 2000s by Roy Fielding in his dissertation "Architectural Styles and Network Design Software Architectures" [8]. Prior to this, REST architecture has been used in many projects under the IETF and W3C. In the thesis itself, you can’t find the terms “web service” or SOA. REST architecture was proposed for the proper design of distributed hypermedia systems, according to other words of what is called the World Wide Web today. To take Fielding’s thesis seriously, I’ll say that Roy is an architect of HTTP 1.1, a co-author of Internet standards for HTTP and URI [10]. In general, he is a serious and famous man.

In order for a distributed system to be considered as designed according to the REST architecture, it is necessary that it satisfy the following criteria:

  1. Client-Server. The system should be divided into clients and into servers.
  2. Stateless. The server should not store any customer information. The request should contain all the necessary information to process the request and, if necessary, identify the client.
  3. Cache ․ Each answer must be marked whether it is cacheable or not.
  4. Uniform Interface. Universal interface between system components.

    To obtain a universal interface, the following restrictions are introduced:

    • Identification of resources.

      In a REST resource, everything that can be given a name is. For example, a user, an HTML document, an image, a registered user, a red jersey, a hungry dog, the current weather, etc. Each resource in REST must be identified by means of a stable identifier, which does not change when the state of the resource changes. In our case, the identifier in REST is the URI.

    • Manipulation of resources through representations.

      The view in REST is used to perform actions on resources. The resource representation is the current or desired state of the resource. For example, if the resource is a user, then the view may be an XML or HTML description of that user.

    • Self-descriptive messages.

      By self-descriptiveness is meant that the request and the response must keep in itself all the necessary information for their processing. There should be no additional messages or caches to handle a single request.

    • HATEOAS (hypermedia as an engine of application state).

      This item means that hypertext should be used to navigate the API [9]. I note that in the case of SOA, the service description is used for this.

      Consider this item in more detail.

      In the example below, the request for receiving a balance in the response indicates not only a balance, but also actions that can be performed with the account.
       GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">100.00</balance> <link rel="deposit" href="/account/12345/deposit" /> <link rel="withdraw" href="/account/12345/withdraw" /> <link rel="transfer" href="/account/12345/transfer" /> <link rel="close" href="/account/12345/close" /> </account> 


      Consider the same example with a negative balance:
       GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">-25.00</balance> <link rel="deposit" href="/account/12345/deposit" /> </account> 


      As you can see, in the answer there are no references to deposit and transfer, since these actions are not available for this account.

  5. Layered System. In REST, it is allowed to divide the system into a hierarchy of layers, but with the condition that each component can only see components of the next layer itself. For example, if you call PayPal and he in turn calls Visa, you do not need to know anything about calling Visa.

  6. Code-On-Demand. REST allows the loading and execution of a code or program on the client side.

And so, if a distributed system satisfies all six given points, then we can say that it is arranged according to the REST architecture, and such a web service in this case is called the RESTful service.

As you have already noticed in these paragraphs, nothing is said about GET, PUT, POST and DELETE requests, JSON, HTTP encoding, etc.

REST is just an architecture, it is not tied to any protocol in any way.

Surely you have already noticed that there is nothing surprising and new in the REST architecture. New was in REST in 2000, when the web just began to develop. To better understand REST and its significance, imagine that the web is a distributed hypermedia system, where each site is hypertext.

Then of course the question arises - and what we see and do in practice is what? On the Internet, you can find a lot of controversy about how the RESTful service should look and how it should not. What HTTP methods should be used and what not? In general, as is already clear, all these discussions do not have a theoretical basis, since there is no specification about the RESTful service. One project may decide that POST will be used to create a new record, another to update, and a third to delete. These solutions are not related to REST architecture.

REST & Richardson Maturity Model


And so, how is REST related to web services? What services can be considered RESTful and which ones are not? What do you get if your service will satisfy all the points of Fielding? I will answer these questions in turn:

  1. REST architecture has proven itself in the past 16 years in the practice of the web. Since web services are part of the web, many companies / developers / researchers have decided to use the REST architecture in the case of web services, which will improve the scalability of components, ensure security, independent deployment, etc.

  2. If the web service satisfies all Fielding criteria, then it can be considered RESTful, regardless of whether the HTTP DELETE method is used to delete entries or not. I will add that in the web, the frequently used methods are GET and POST and if the web service should be as close to the web as possible, then using PUT and DELETE is also somehow not correct.

  3. Although Fielding wrote about the web and distributed hypertext systems, I still copy some of his thesis. In English, this sounds more convincing.
    The REST provides a set of architectural constraints, it emphasizes the scalability of the structure, the interoperability of
    encapsulate legacy systems.

Of course, everything sounds very cool, but is it necessary to have your web service designed by REST or is it just a trend? Let's look at Leonard Richardson's RMM (Richardson Maturity Model) model.

After analyzing several hundred web services [11], an RMM model was proposed for assessing quality, or as Richardson called it, the maturity of a web service. The RMM model consists of 4 levels. If your service corresponds to the last level, then you can consider it RESTful. Below I will give examples and drawings from [12], which according to the author were checked by Aaron Schwartz, Leonard Richardson and other famous people. All examples are based on the following story: I want to make an appointment with a doctor. From the web service I need to get free reception hours for a specific date and then make an appointment. And so, consider all these four levels in this example.

Level 0: One URI, one HTTP method.


Here HTTP is used only for the interaction of components of a distributed system. Of the methods used only one, for example POST. As you may have guessed, such web services are the XML-RPC and SOAP protocols.

image

Example: Getting free hours of Dr. mjones on the date 2010-01-04.
 POST /appointmentService HTTP/1.1 [various other headers] <openSlotRequest date = "2010-01-04" doctor = "mjones"/> 

 HTTP/1.1 200 OK [various headers] <openSlotList> <slot start = "1400" end = "1450"> <doctor id = "mjones"/> </slot> <slot start = "1600" end = "1650"> <doctor id = "mjones"/> </slot> </openSlotList> 


Example: Register for an appointment with Dr. mjones from 2:00 pm to 2:50 pm. (here, in the request, you probably would need to specify a date, but I will not change the original example).
 POST /appointmentService HTTP/1.1 [various other headers] <appointmentRequest> <slot doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> </appointmentRequest> 

 HTTP/1.1 200 OK [various headers] <appointment> <slot doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> </appointment> 


XML is used here only as an example, in its place there could be JSON, HTML, etc. The web service has only one URL (relative URL): / appointmentService. The requested function is specified in the request body.

If your service corresponds to level 0, then it is still a child.

Now consider the same example when working with a web service with a level of 1.

Level 1: Multiple URIs, one HTTP method.


Services at this level use the concept of "divide and conquer." The service introduces the concept of resources and uses the URL of the resource to act on a specific resource.

image

Example: Getting free hours of Dr. mjones on the date 2010-01-04.
 POST /doctors/mjones HTTP/1.1 [various other headers] <openSlotRequest date = "2010-01-04"/> 

 HTTP/1.1 200 OK [various headers] <openSlotList> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/> </openSlotList> 


Example: Register for an appointment with Dr. mjones from 2:00 pm to 2:50 pm.
 POST /slots/1234 HTTP/1.1 [various other headers] <appointmentRequest> <patient id = "jsmith"/> </appointmentRequest> 

 HTTP/1.1 200 OK [various headers] <appointment> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> </appointment> 


And so, if you want to perform some kind of action with a doctor, then you need to use the relative URL / doctors, and if your action is related to a visit, then the URL / slots. If we compare the first level service with the zero level service, then in the latter case there is only one resource, and this resource is the web service itself.

If your service is level 1, then it is a teenager.

Level 2: Multiple URIs, each supporting different HTTP methods (Proper use of HTTP).


And so, at level 1, all web service methods were separated using resources, but with a resource you can perform a bunch of actions. In order for these actions to be somehow logically separated, use the HTTP ability to send and receive operations with different methods: GET, HEAD, POST, PUT, DELETE, TRACE, CONECT. For example, if the method is reading, you can use GET, if to create POST or PUT In principle, it is possible and vice versa, but since in HTTP these methods have some concepts and characteristics, it is better that these concepts are the same as in the web service, otherwise you can get a cached method for creating a resource. In other words, which method you will use for which operations, the question of the proper use of the HTTP protocol is already ․

image

Perhaps it is time for examples:

Example: Getting free hours of Dr. mjones on the date 2010-01-04.
 GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1 Host: royalhope.nhs.uk 

 HTTP/1.1 200 OK [various headers] <openSlotList> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/> </openSlotList> 


Example: Register for an appointment with Dr. mjones from 2:00 pm to 2:50 pm.
 POST /slots/1234 HTTP/1.1 [various other headers] <appointmentRequest> <patient id = "jsmith"/> </appointmentRequest> 

 HTTP/1.1 201 Created Location: slots/1234/appointment [various headers] <appointment> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> </appointment> 


With the introduction of different HTTP methods, the need to return the correct HTTP status codes is also introduced. For example, the request to create a meeting, if it was created, then the code 201 should be returned. If during your actions someone was already registered on the selected day and hour, the code 409 conflict should be returned, etc. Again, the point is to use the HTTP protocol correctly ․

If your service corresponds to level 2, then it is already an adult man.

Level 3: HATEOAS Resources themselves describe their capabilities and relationships.


HATEOAS (Hypertext as the Engine of Application State), which in my opinion is a requirement for hypermedia, but I don’t know how relevant it is for web services. Nevertheless, HATEOAS is a feature of the web service to return actions in the form of URLs that can be executed with the resource of interest to you.

image

Since HATEOAS has already been discussed above, here I will give only examples.

Example: Getting free hours of Dr. mjones on the date 2010-01-04.
 GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1 Host: royalhope.nhs.uk 

 HTTP/1.1 200 OK [various headers] <openSlotList> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"> <link rel = "/linkrels/slot/book" uri = "/slots/1234"/> </slot> <slot id = "5678" doctor = "mjones" start = "1600" end = "1650"> <link rel = "/linkrels/slot/book" uri = "/slots/5678"/> </slot> </openSlotList> 


Each free hour has a URL to perform actions on it, in this case, registration for this hour.

Example: Register for an appointment with Dr. mjones from 2:00 pm to 2:50 pm.
 POST /slots/1234 HTTP/1.1 [various other headers] <appointmentRequest> <patient id = "jsmith"/> </appointmentRequest> 

 HTTP/1.1 201 Created Location: http://royalhope.nhs.uk/slots/1234/appointment [various headers] <appointment> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> <link rel = "/linkrels/appointment/cancel" uri = "/slots/1234/appointment"/> <link rel = "/linkrels/appointment/addTest" uri = "/slots/1234/appointment/tests"/> <link rel = "self" uri = "/slots/1234/appointment"/> <link rel = "/linkrels/appointment/changeTime" uri = "/doctors/mjones/slots?date=20100104@status=open"/> <link rel = "/linkrels/appointment/updateContactInfo" uri = "/patients/jsmith/contactInfo"/> <link rel = "/linkrels/help" uri = "/help/appointment"/> </appointment> 


The advantage of HATEOAS is that it allows web services developers to change URIs independently of clients. In addition, the web service itself describes itself without any WSDL. To properly represent HATEOAS, submit a web site from static pages. You open the main page, and there already links to everything else. To go to a website and find something there, there is no need to read some document on this website, something like an API document. Again, my subjective opinion on the need for a web service to support HATEOAS is rather pessimistic.

If your service corresponds to level 3, then it can already be called RESTful and of course an old man with good experience.

Conclusion


If you are reading these lines it means either you have read the whole article and reached the conclusion, or because of a lack of time, you have scrolled through the main article and read only the conclusion.

Since the second case is more common than the first, I will give the main concepts:

  1. A web service is one of the methods for implementing an SOA architecture.
  2. A web service protocol is a specific implementation of a web service (XML-RPC, SOAP, JSON-RPC, etc.).
  3. REST is an architecture that was proposed in 2000 and was used to properly create components of the web and distributed hypermedia systems as a whole.
  4. The question of how SOAP differs from REST is almost the same as asking, what distinguishes a bison from a predator. SOAP is a protocol that has a specification, and REST is an architecture that you can use to create web services using HTTP and a URL.
  5. Richardson Maturity Model is a model proposed by Leonard Richardson to assess the maturity of a web service. The concepts of “child”, “teenager”, “man” and “old man” I myself introduced in order to better represent the layer of the RMM model.

Whether the web service is a child or an old man is your choice. If you or your company develops both the server part of the application and the client part, then I think there is no need for your service to satisfy all RMM items, especially HATEOAS. “Man” or “teenager” will easily cope with this task. And if you are developing something like amazon, you should have several thousand clients, of which you have no idea, then the “old man” is probably the best to deal with. If your service has very few functions, then give this work to the “child”, he knows how to merge everything into one heap (into one resource).

Literature


1. www.oasis-open.org/committees/download.php/19679/soa-rm-cs.pdf
2. www.opengroup.org/standards/soa
3. www.w3.org/TR/ws-arch/ #whatis
4. en.wikipedia.org/wiki/List_of_web_service_protocols
5. xmlrpc.scripting.com/spec.html
6. www.jsonrpc.org/specification
7. www.w3.org/TR/soap
8. www.ics. uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf
9. restcookbook.com/Basics/hateoas
10. roy.gbiv.com/untangled/about
11. www.crummy.com/writing/speaking/2008-QCon/ act3.html
12. martinfowler.com/articles/richardsonMaturityModel.html

Source: https://habr.com/ru/post/319984/


All Articles