20240923

Architectural Styles and the Design of Network-based Software Architectures by Roy Thomas Fielding

From my understanding, there are no definitive definitions of RESTful API, though there are some guidelines proposed by Roy Fielding and accumulated best practices. (send me an email or create a pull request to crrect me)

Reading Roy Fielding's dissertation offered me some insights, but it's been a long time already, and I completely forgot what I understood :sweat: This is a retry.

CHAPTER 5: Representational State Transfer (REST)

This chapter introduces and elaborates the Representational State Transfer (REST) architectural style for distributed hypermedia systems, describing the software engineering principles guiding REST and the interaction constraints chosen to retain those principles, while contrasting them to the constraints of other architectural styles.

In this chapter, the author explains REST by adding constraints one by one.

Client-Server

The first constraints added to our hybrid style are those of the client-server architectural style…

Separation of concerns is the principle behind the client-server constraints. By separating the user interface concerns from the data storage concerns, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components. Perhaps most significant to the Web, however, is that the separation allows the components to evolve independently…

Stateless

We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style…, such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

This constraint induces the properties of visibility, reliability, and scalability.

Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request.

Reliability is improved because it eases the task of recovering from partial failures.

Scalability is improved because not having to store state between requests allow the server component to quickly free resources, and further simplifies implementation because the server doesn't have to manage resource usage across requests.

Like most architectural choices, the stateless constraint reflects a design trade-off.

The disadvantage is that it may decrease network performance by increasing the repetitive data (per-interaction overhead) sent in a series of requests, since that data cannot be left on the server in a shared context.

In addition, placing the application state on the client-side reduces the server's control over consistent application behavior, since the application becomes dependent on the correct implementation of semantics across multiple client versions.

Cache

In order to improve network efficiency, we add cache constraints to form the client-cache-stateless-server style… Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response if cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.

I only have experience with Django and FastAPI, but I cannot think of any real-life implementations having a flag to indicate a response is cacheable or not. I guess I should do some research on it.

Uniform Interface

The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components. By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interaction is improved. Implementations are decoupled from the services they provide, which encourages independent evolvability.

The trade-off, though, is that a uniform interface degrades efficiency, since information is transferred in a standardized form rather than one which is specific to an application's needs. The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.

In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.

These constraints will be discussed in Section 5.2.

I guess it derives the common RESTful API structure such as the common patterns of GET / or PUT /{id}, but I'm not totally sure.

Layered System

In order to further improve behavior for Internet-scale requirements, we add layered system constraints… the layered system style allows an architecture to be composed of hierarchical layers by constraining component behavior such that each component cannot “see” beyond the immediate layer with which they are interacting. By restricting knowledge of the system to a single layer, we place a bound on the overall system complexity and promote substrate independence.

Layers can be used to encapsulate legacy services and to protect new services from legacy clients, simplifying components by moving infrequently used functionality to a shared intermediary. Intermediaries can also be used to improve system scalability by enabling load balancing of services across multiple networks and processors.

The primary disadvantage of layered systems is that they add overhead and latency to the processing of data, reducing user-perceived performance. For a network-based system that supports cache constraints, this can be offset by the benefits of shared caching at intermediaries…

The combination of layered system and uniform interface constraints induces architectural properties similar to those of the uniform pipe-and-filter style (Section 3.2.2). Although REST interaction is two-way, the large-grain data flows of hypermedia interaction can each be processed like a data-flow network, with filter components selectively applied to the data stream in order to transform the content as it passes.

I better check out pipe-and-filter style. I don't quite understand this part.

Within REST, intermediary components can actively transform the content of messages because the messages are self-descriptive and their semantics are visible to intermediaries.

Code-On-Demand

The final addition to our constraint set for REST comes from the code-on-demand style of Section 3.5.3… REST allows client functionality to be extended by downloading and executing code in the form of applets or scripts. This simplifies clients by reducing the number of features required to be pre-implemented. Allowing features to be downloaded after deployment improves system extensibility. However, it also reduces visibility, and thus is only an optional constraint within REST.

… For example, if all of the client software within an organization is known to support Java applets, then services within that organization can be constructed such that they gain the benefit of enhanced functionality via downloadable Java classes. At the same time, however, the organization's firewall may prevent the transfer of Java applets from external sources, and thus to the rest of Web it will appear as if those clients do not support code-on-demand.

An optional constraint allows us to design an architecture that supports the desired behavior in the general case, but with the understanding that it may be disabled within some contexts.

I'm not very familiar with Java or applets right now, and don't understand this constraint quite well. I will skip this for now and come back here after some time. I hope I have relevant information in my brain and can understand this part.

I feel tired. will go to bed early today.


Protein shake 400 Teriyaki bowl 700 Yogurt 300 Fruits 300 Bagels 600

Total 2300 kcal (will go back to the diet mode tomorrow)


MUST:

TODO:


index 20240913 20240924