RESTFul APIs: Networking
July 4th, 2020
This is the first article in a five part series on RESTful APIs.
RESTful APIs are usually built over the internet. But what is the internet?
What is the internet?
From Wikipedia, we learn that:
The Internet is the global system of interconnected computer networks that uses the Internet protocol suite (TCP/IP) to communicate between networks and devices.
At it's base, the internet is a huge network of computers that run different types of protocols for communication with one another. A protocol is a set of rules and standards that define the language that devices use to communicate. The conceptual model and communication protocols used are called the Internet Protocol Suite. It has four layers, each layer treating the underlying one as a black box.
The application layer is the scope that creates and communicates data. Application layer protocols are: HTTP/S, SSH, FTP, SMTP etc.
The transport layer provides the channel for the communication needs, host-to-host connectivity, and end-to-end messaging regardless of the data format. The most important transport layer protocols include TCP, UDP, IP, ICMP.
The internet layer provides a uniform networking interface that abstracts the actual layout of the network. Data is sent from the source network to the destination network via routing. The primary protocol is IP; it defines the IP addresses. Examples of Internet layer protocols: IP, ICMP, IGMP.
The link-layer operates in the local network and defines the mechanisms for communication in that scope. It moves packages between the internet layer and local network hosts.
A single machine can have multiple applications running on it: an HTTP server, an FTP server and/or an SSH server, etc. Ports allow a single machine to have multiple applications that communicate via the same physical interface.
Most web developers build internet applications on top of TCP/IP and HTTP/S, which are abstracted by the operating system, client, framework, and tools. You don't need to know the intricacies of the TCP/IP stack for small to medium-sized applications. As the application grows in complexity and size, some issues that require lower layer protocol knowledge to solve may arise. As a beginner, you don't need to know exactly how the internet works. Focusing on HTTP is enough. As you grow as a web developer, networking knowledge will advance your skillset. Depending on the problems you work on, you might not be able to solve them without proper networking knowledge.
URL & DNS
On the internet, resources have a Universal Resource Locator, in short: URL. URLs are used to identify specific resources. The URL is not the resource, like the house is not the address. In other words, the URL is just a way to find it the resource.
Example of an URL:
We can see that the URL contains all the necessary information to find a unique resource. The protocol, the Fully Qualified Domain Name (FQDN or the location of the machine), the port on the machine where the server is bind to, the path to the resource, URL query information, and resource fragments.
The Internet uses the IP protocol, so how is the domain being mapped with the IP address of a machine? The DNS (Domain Name Server) service does that. The DNS is responsible for mapping domains with the machine IP.
For every domain registered, there is an IP address that corresponds to the physical machine which is responsible for responding to the request made.
Once you know the IP address, the ISP has the responsibility of sending it via the internet infrastructure.
Browsers are applications that run on the user machine, hence the name, client application. They use the HTTP/S protocol for communication with a server that also understands the HTTP/S protocol and the lower level protocols that HTTP/S is built on.
Let's recap and see how this all fits together.
Let's say a friend wants to send you an URL (link) to a cool article that he just read. You receive it via an email for example. Click on the link and the browser starts with the URL sent to the address bar.
This way the browser understands that it must make a GET request, requesting the article resource. He knows only the FQDN so it uses that to query the DNS service which returns the actual IP of the machine responsible for sending the response. The port is implied from the default HTTP/S port (80 or 443) and the request is sent.
HTTP is the protocol usually used for client-server applications. Web applications and websites are client-server applications. It uses a single direction channel, request-response, meaning that it works in request/response pairs. For every client request, a server must return a response even if the resource does not exist and a 404 code is used. The request is initiated by the client (usually a browser), it's intercepted by the server and the server responds with the data. A server cannot initiate a request to the clients. A request can be kept alive and the server can push data as needed with SSE or, for bi-channel communication, web sockets can be used.
A request is formed from one of the requests verbs, a header, and, optionally, a body. The verb specifies the action intended. The header contains meta-information about the request. The body may be missing and in case it is not, it should contain the data needed by the server.
The request verbs can be one of GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, TRACE and CONNECT.
A response is formed from a status code, a header, and the body. The status code returns the status of the request. Every response has a header with a status code in the range [1xx..5xx]. The body of the response contains the information that was requested, for example, it can be an image, an XML, or a JSON.
The GET verb means that the client wants to retrieve the resource specified by the URL. In general, GET requests do not have any effect on the data being served.
The POST verb means that the client sends information to the server. It usually implies the creation of a new resource.
The PUT verb means that the client wants to update the information regarding a specific resource with the new information sent.
The DELETE verb means that the client wants to remove a specific resource or collection of resources.
The CONNECT verb starts two-way communications with the requested resource. It can be used to open a tunnel.
The OPTIONS verb requests permitted communication options for a given URL or server.
The TRACE verb performs a message loop-back test along the path to the target resource.
GET, HEAD, and OPTIONS requests are safe methods, no meaningful state should be changed on the server.
GET, PUT, and DELETE requests are idempotent, running one of the requests with the same information once or a hundred times means the same thing.
POST on the other hand is not safe nor idempotent because the same request creating a resource called a thousand times may create a thousand resources.
SSL(Secure Sockets Layer) is a standard technology for securing internet connections. HTTP over SSL is HTTPS, they are equivalent to each other with the exception that HTTPS is encrypted, thus more private and secure.
By default/convention the port 80 is used for applications that use the HTTP protocol and port 443 for applications that use HTTPS protocol. It is not mandatory so if you have multiple applications that communicate with each other via HTTP/S, other ports can be used.
Status codes are split into 5 classes, 1xx for information, 2xx for success, 3xx redirection, 4xx client error, 5xx for server errors.
So how should we use the status codes? 200(OK) is a status code that is more generic and signifies that the request was successful. It is usually used for file requests like web pages(.html).
For creating a resource, a more specific status code is 201(Created). This is used with the POST verb and will send back the created entity via the response.
If we don't want to send back anything as a response, then the 204(No content) is the proper status. Usually used with the DELETE verb.
If the client does not use the API correctly, then an error from the 4xx class should be used. If the server is at fault, then an error from the 5xx class should be used.
The 400(Bad Request) status code is as generic as it gets. One can use this status code to signal to the client that the request is malformed.
If you want to be more specific with authorization/authentication issues the proper status code is 401(Unauthorized) if the client is not authenticated (missing JWT for example) and 403(Forbidden) if the client is authenticated correctly but it does not have permissions to CRUD that resource.
PUT or DELETE works on specific resources like a user. If they are applied to 'collection' type resources a 405(Not allowed) can be used.
If the request cannot find the resource that acts as a single entity, a 404(Not found) is the correct status code. For resources that act as a collection an empty 200(OK) or 204(No content) can be used.
That's all for now, next REST definition.