Learn the key principles of web service design


It is not difficult to create a RESTful webservice in Java. In fact, frameworks like Spring Boot, Eclipse MicroProfile, and Jakarta Enterprise Edition make developing RESTful Java applications relatively easy.

But the problem with many RESTful web services is not their development but their design. This RESTful API tutorial discusses the problem of designing web services and highlights common mistakes software developers make when creating a RESTful API.

Many Java frameworks, such as Spring Boot and Jakarta EE, facilitate the development of RESTful web services.

A tutorial on RESTful APIs

Designers have two key things to consider when developing a RESTful Java API:

  1. The URL pattern
  2. Which HTTP method to use

The first important principle of this RESTful API tutorial is that resources should always be accessible through URLs that uniquely identify them.

This should be a new concept for anyone who has used a Web browser. When we access a web page or download a web-based PDF file, we point our browser to a URL that identifies that resource. The same concept applies when accessing server-side resources with a RESTful Java web service. If a jQuery or Angular client needs to manipulate a resource, there must be a unique URL that the associated JavaScript code can use to identify the RESTful resource in question.

Example RESTful URL

I often prototype software development concepts with a small rock-paper-scissors application. In this app, I usually code a component that keeps track of wins, losses and connections. An effective RESTful API that allows users to interact with the partition would include the following URL in its design:

www.mcnz.com/rps/score

When users access this URL – through the browser, through a RESTful JavaScript application, or through a Spring Boot MVC component – they receive a representation of the current score. A RESTful Java API that supports JSON can return a result like this:

{ "wins":"5", "losses":"3", "ties": "0"}

If a RESTful JavaScript client is only interested in earnings, the URL should follow a predictable format where earnings are a subresource of score:

www.mcnz.com/rps/score/wins → returns { "wins":"5"}

In fact, returning the number of wins in JSON format is probably excessive. Simply returning the number of wins as base text makes the result easily usable by all clients, whether or not they can parse JSON or not. So the following would be preferable:

www.mcnz.com/rps/score/wins → returns "5"

Losses and ties should follow a similar RESTful URL format:

www.mcnz.com/rps/score/losses → returns "3"
www.mcnz.com/rps/score/ties → returns "0"

Example of RESTful HTTP methods

All of the RESTful API examples shown so far assume a simple GET invocation. The HTTP protocol provides a number of different methods for interacting with a RESTful resource through a URL. When presented with a URL, servers usually assume it is a GET request. However, a RESTful API designer must consider at least three other HTTP methods, namely POST, PUT, and DELETE.

Principles of RESTful Design

To discuss the HTTP method, there are some important RESTful design rules to follow. RESTful Java API designers tend to go astray if they violate these rules.

The first rule is that GET invocations can never change the state of a RESTful resource on the server. Our RESTful API fully respects this rule.

RESTful PUT and DELETE methods

Although not exactly a hard and fast rule, the PUT and DELETE methods roughly correspond to the concept of save and delete. If designers want to remove a resource from the server, they should use the HTTP DELETE method. If they need to create a new resource or update an existing one, they should use the PUT method.

Idempotent methods

The PUT and DELETE methods are relatively simple to save and delete data. This is the other PUT and DELETE rule where RESTful Java API designers tend to have issues. This second rule requires idempotence from HTTP methods.

If something is idempotent, it can be done over and over, and the result will always be the same.

For example, imagine that a client has made a RESTful DELETE request to delete record 271. This call can be made once, or 100 times. The the end result will always be the same – so long, record 271. This scenario below is idempotent.

HTTP DELETE || www.mcnz.com/rps/score?record=271 #Good RESTful Java design

Compare this with a request to remove the 10 oldest records from the database.

HTTP DELETE || www.mcnz.com/rps/score?oldRecordsToDelete=10 #Bad RESTful Java design

With this example, the RESTful URL would leave the database in a different state with every new invocation – up to the point where every record in the database is deleted. This method is not idempotent and therefore violates a fundamental principle of the RESTful API.

PUT and RESTful API designed

The PUT method must also be idempotent. So if one were to change the number of wins from the current value in the database to 10, a good Java RESTful API would look like this:

HTTP PUT || www.mcnz.com/rps/score/wins?value=10

You could call this method over and over, and after each invocation, the server would be left in the same state. The number of wins would be 10. This RESTful Java API is idempotent. Compare that with a method that adds 10 wins each time it’s invoked:

HTTP PUT || www.mcnz.com/rps/score/wins?add=10

This method is not idempotent because, with each invocation, the number of victories passes to a new value. The number of wins can start at 10 the first time, 20 when summoned a second time, and 30 the next. The end state of the resource is unpredictable with this method. This is not a dumb and bad RESTful API design.

Technically speaking, the query parameters at the end of a URL should only be used for one purpose: to query. In this example, we are using a query parameter to pass a payload to the server. This makes the example simpler, but it also violates the spirit of the intended use of a query parameter. In a future RESTful API design tutorial, we’ll show how passing a JSON string as part of the payload during a PUT call is a better design than using request parameters.

Flexible RESTful API design

So, we saw in this RESTful API tutorial that deleting the 10 oldest records from a database is a bad use of the DELETE method, and incrementing a number is a bad application of the PUT method. . Does that mean we can’t do these things with a RESTful API? Not at all.

So far, this RESTful API tutorial establishes two very important rules:

  1. The GET invocation must not change the state of a resource.
  2. The PUT and DELETE methods must be idempotent.

But note that we haven’t said anything about the POST method. The POST method can be used in any scenario that does not fall under the above rules. So, if you want to prune the 10 oldest records in the database, use the POST method. If you want to increase the number of wins by 10, use the POST method again. The POST method is the Swiss army knife of RESTful design.

HTTP POST || www.mcnz.com/rps/score/wins?add=10
HTTP POST || www.mcnz.com/rps/score?oldRecordsToDelete=10

Of course, there is a danger if you approach the POST method as a panacea for all the tough cases your RESTful API faces. Just because you aren’t breaking idempotence rules or using the GET, PUT, and DELETE methods doesn’t mean that you’ve properly designed a RESTful API. The overuse of the POST method is in itself a RESTful anti-model.

RESTful design anti-patterns

Far too often you’ll see a so-called RESTful system where designers have turned every permutation of their API into a POST invocation. Just because you haven’t broken important RESTful principles doesn’t mean you’ve built an effective RESTful API. The trend of heavy use of the POST method often occurs when RESTful API designers take a service-based approach to their problem area. When building RESTful APIs, it’s important to always take a resource-based approach to your system.

There is a lot to learn, such as best practices for passing payload data to the server, how to structure URLs to identify resources, and how to avoid the trap of taking a service-based approach to resource-based design. . We’ll cover them in the following RESTful API tutorials. But a solid foundation in structuring URLs and the proper use of HTTP methods is the foundation of every beautiful resource based API never designed.

See all the videos


Source link

Previous Progress Step UI Design Templates: Tips, Giveaways, and Code Snippets
Next 7 container design patterns you need to know