CS 346 (W23)
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Web Services

As originally designed, a web server and web browser are a great example of a client-server architecture.

A web server is service running on a server, listening for requests at a particular port over a network, and serving web documents (HTML, JSON, XML, images). The payload that is delivered to a web browser is the content, which the browser interprets and displays. When the user interacts with a web page, the web browser reacts by making requests for additional information to the web server.

Over time, both browser and web server have become more sophisticated, allowing servers to host additional content, run additional programs as needed, and work as part of a larger ecosystem that can distribute client requests across other systems.

Web technologies are interesting to us because they can be the basis for a robust service request mechanism. We’ll explore that in this section.

HTTP Protocol

The Hypertext Transfer Protocol (HTTP) is an application layer protocol that supports serving documents, and processing links to related documents, from a remote service.

HTTP functions as a request–response protocol:

  • A web browser is a typical client, which the user is accessing. A web server would be a typical server.
  • The user requests content through the browser, which results in an HTTP request message being sent to the server.
  • The server, which provides resources such as HTML files and other content or performs other functions on behalf of the client, returns a response message to the client. The response contains completion status information about the request and may also contain requested content in its message body.

HTTP Request/Response - ntu.edu

Request Methods

HTTP defines methods to indicate the desired action to be performed on the identified resource.

What this resource represents, whether pre-existing data or data that is generated dynamically, depends on the implementation of the server. Often, the resource corresponds to a file or the output of an executable residing on the server. Method names are case sensitive.

  • GET: The GET method requests that the target resource transfers a representation of its state. GET requests should only retrieve data and should have no other effect.

  • HEAD: The HEAD method requests that the target resource transfers a representation of its state, like for a GET request, but without the representation data enclosed in the response body. Uses include looking whether a page is available through the status code, and quickly finding out the size of a file (Content-Length).

  • POST: The POST method requests that the target resource processes the representation enclosed in the request according to the semantics of the target resource. For example, it is used for posting a message to an Internet forum, or completing an online shopping transaction.

  • PUT: The PUT method requests that the target resource creates or updates its state with the state defined by the representation enclosed in the request. A distinction to POST is that the client specifies the target location on the server.

  • DELETE: The DELETE method requests that the target resource deletes its state.

Web Services

In a general sense, web servers are providing services to clients through web protocols. We can leverage this infrastructure and use HTTP as the basis for a more generalized service protocol that can target more than just web browsers.

In other words, we can use HTTP, GET and POST requests to request data not just to be displayed in a browser, but for other purposes. HTML, JSON and other web standards are ideal for serving up small-medium sized data.

REST

REpresentational State Transfer (REST), is a software architectural style that defines a set of constraints for how the architecture of an Internet-scale system, such as the Web, should behave.

  • REST was created by Roy Fielding in his doctoral dissertation in 2000.
  • It has been widely adopted and is considered the standard for managing stateless interfaces for service-based systems.
  • The term “RESTful Services” is commonly used to describe services built using standard web technologies that adheres to these design principles.
It’s important to recognize that REST is not a protocol, but a set of architectural guidelines for the effective use of these technologies. It’s become an informal standard through common use.

Here’s a diagram that shows the relationships between REST principles, methods and responsibilities.

REST API Design - https://blog.devgenius.io

Principles

  1. Client-Server. By splitting responsibility into a client and service, we decouple our interface and allow for greater flexbility in how our service is deployed. This provides portability, and the potential for scalability of our service if needed (e.g. we can change how the service is provided with potentially no client-side changes).
  2. Layered System. The client has no awareness of how the service is provided, and we may have multiple layers of responsibility on the server. i.e. we may have multiple servers behind the scenes, with aggregated data being returned through the single service API.
  3. Cacheable. With stateless servers, the client has the ability to cache responses under certain circumstances which can improve performance.
  4. Code On-Demand. Clients can download code at runtime to extend their functionality (not really a property of the service, but the client architecture).
  5. Stateless. The service does not retain state i.e. it’s idempotent. Every request that is sent is handled independently of previous requests. That does not mean that we cannot store data in a backing database, it just means that we have consistency in our processing.
  6. Uniform Interface. Our interface is consistent and well-documented. Using the guidelines below, we can be assured of consistent behaviour.

Request Methods

Use the HTTP request methods that we’ve described in a common-sense way with your data.

  • GET: Use the GET method to read data. GET requests are safe and idempotent.

  • POST: Use a POST request to STORE data i.e. create a new record in the database, or underlying data model. Use the request payload to include the informaetion that you want to store. You have a choice of content types (e.g. multipart/form-data or x-www-form-urlencoded or raw application/json, text/plain…) – we strongly recommend straight json.

  • PUT: A PUT request should be used to update existing data.

  • DELETE: Use a DELETE request to delete existing data.

API Guidelines

Here’s some guidelines on the use of REST to create a web service [Cindrić 2021].

  1. Use JSON for requests and responses
  • it’s easier to use, write and read
  • it’s faster than XML and consumes less memory space
  • it doesn’t need special dependencies or packages to parse it
  • every meaningful programming language has great support for it
  1. Use meaningful structures for your endpoint

Every URL that you support is an endpoint. Think of them like function calls: you want them to be clear and readable. The guidelines here are also quite simple:

  • use nouns instead of verbs; use plural instead of singular
  • layered requests in a meaningful way. i.e. GET /customers should return a list of customers; GET /customers/1 should return data for customer ID=1.

Good 👍🏻

  • GET /users
  • POST /users
  • GET /users/23
  • PUT /users/23
  • DELETE /users/23
  • GET /users/23/comments

Bad 👎🏻

  • GET /user/23
  • GET /listAllUsers
  • POST /user/create
  • PUT /updateUser/23
  • GET /userComments/23
  1. Be Consistent

If you define a JSON structure for a record, you should always use that structure: avoid doing things like ommitting empty fields (instead, return then as named empty arrays).

e.g. notice the empty comment field - don’t leave it out!

{
   "status":true,
   "message":"Article list was a success",
   "articles":[
      {
         "title":"Sample title 1",
         "description":"Sample description 1",
         "image":"https://domain.com/image-1,jpg",
         "uuid":"eec33d99-e955-408e-a64a-abec3ae052df",
         "comments":[]
      }
     ]
}

HTTP is a well-defined protocol. We could certainly build a service ourselves, from-scratch, that utilizes HTTP to serve client requests. However. designing a web server to handle HTTP properly is a huge undertaking.

Instead, we can look at commercial frameworks that provide libraries and starter code. Using frameworks for web services is anologous to using JavaFX or Jetpack Compose for building a UI. Yes you could create everything yourself from first-principles, but most of the time you’re better off using existing libraries that have been well-designed and tested. Frameworks include Spring from VMware, and Ktor from JetBrains. We’ll walkthrough an example using Spring, which is the most popular and well-documented framework.