0% found this document useful (0 votes)
125 views33 pages

The Power of REST - Greg L. Turnquist

The document discusses arguments that are commonly made against RESTful APIs and argues they are straw man arguments. It addresses four common counterarguments: 1) That REST requires too many HTTP requests ("hops") to retrieve related data, but notes REST does not prevent embedding related data to reduce hops. 2) That REST APIs return too much unnecessary data, but the example given would involve a small amount of extra data. 3) That clients should be able to write SQL queries directly rather than use REST's HTTP methods, but queries are better suited to data stores rather than public APIs. 4) That GraphQL solves problems with REST, but REST allows APIs to evolve without breaking clients, which was

Uploaded by

NITHISHKUMAR.S
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
125 views33 pages

The Power of REST - Greg L. Turnquist

The document discusses arguments that are commonly made against RESTful APIs and argues they are straw man arguments. It addresses four common counterarguments: 1) That REST requires too many HTTP requests ("hops") to retrieve related data, but notes REST does not prevent embedding related data to reduce hops. 2) That REST APIs return too much unnecessary data, but the example given would involve a small amount of extra data. 3) That clients should be able to write SQL queries directly rather than use REST's HTTP methods, but queries are better suited to data stores rather than public APIs. 4) That GraphQL solves problems with REST, but REST allows APIs to evolve without breaking clients, which was

Uploaded by

NITHISHKUMAR.S
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

The Power of REST

Greg L. Turnquist
The Power of REST

© 2020 Greg L. Turnquist

All rights reserved. No part of this book may be reproduced, stored in a


retrieval system, or transmitted in any form or by any means, without
the prior written permission of the publisher, except in the case of
brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure
the accuracy of the information presented. However, the information
contained in this book is sold without warranty, either express or
implied. Neither the author, nor its dealers and distributors will be
held liable for any damages caused or alleged to be caused directly or
indirectly by this book.

This author has endeavored to provide trademark information about


all of the companies and products mentioned in this book by the
appropriate use of capitals. However, we cannot guarantee the
accuracy of this information.

All opinions stated are the author’s and do not necessarily reflect those
of the Spring team, Pivotal Software, VMware, Dell EMC, or any other
entity. Any usage of "Spring", "Spring HATEOAS", Spring Boot", "Spring
Framework", "Project Reactor", any other portfolio project, "Pivotal",
"VMware", or any other entity is completely unaffiliated with its
owners. Any excerpts and usages thereof are strictly in the spirit of
"fair use."

Certain outputs have been edited to fit the format of this book. Nothing
of critical value has been left out on purpose.

Published: May 2020

Greg L. Turnquist
c/o The Power of REST
P.O. Box 4042

1
Clarksville, TN 37043
USA

ISBN: 123-45-6789

GregLTurnquist.com/the-power-of-rest

2
Dedicated to my tech friends that LOVE geeking out.

3
4
About the Author
Greg L. Turnquist works on the Spring team as a principal
developer at VMware. He is a committer to Spring HATEOAS,
Spring Data, Spring Boot, R2DBC, and Spring Session for
MongoDB. He also wrote Packt’s best-selling title, Learning
Spring Boot 2.0 2nd Edition. He co-founded the Nashville Java
User Group in 2010 and hasn’t met a Java app (yet) that he
doesn’t like.

Follow him on Twitter @gregturn and subscribe for all his


Spring Boot videos at YouTube.com/GregTurnquist.

5
6
Table of Contents
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1 ......................................................9
Straw man arguments against REST . . . . . . . . . . . . . . . . . . . . 9
REST requires lots of hops . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Rest servces too much data . . . . . . . . . . . . . . . . . . . . . . . . . 11
Just put SQL in the client already!. . . . . . . . . . . . . . . . . . . 12
What problem are you solving?. . . . . . . . . . . . . . . . . . . . . 13
2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
What does REST really do? . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
The Basis of REST. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Evolving an API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Honoring the robustness principle . . . . . . . . . . . . . . . . . . 22
3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Getting the real message of REST out there. . . . . . . . . . . . . 23
How the web does it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Don’t argue the wrong end of things . . . . . . . . . . . . . . . . 26
Don’t preach it, use it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7
8
Straw man arguments against REST

1
Straw man arguments against
REST
I was kind of shocked when I saw Yet Another Posted
Solution to REST. I sighed and commented, and drew the ire
of many. So I figured this might be a good time to gather
some thoughts on REST.

The article I read starts by criticizing REST and offering their


toolkit as the solution. What’s really funny, is that the
problems they ding are not RESTful issues.

REST requires lots of hops

Let’s start with this one:

9
Straw man arguments against REST

As you might notice, this is less than ideal.


When all is said and done we have made 1 +
M + M + sum(Am) round trip calls to our API
where M is the number of movies and
sum(Am) is the sum of the number of acting
credits in each of the M movies. For
applications with small data requirements,
this might be okay but it would never fly in a
large, production system.

Conclusion? Our simple RESTful approach is


not adequate. To improve our API, we might
go ask someone on the backend team to
build us a special /moviesAndActors
endpoint to power this page. Once that
endpoint is ready, we can replace our 1 + M +
M + sum(Am) network calls with a single
request.

This is the classic problem when you run into when fetching
a 3NF (3rd Normal Form) data structure served up as REST.

Tip #1: REST doesn’t prevent you from merging data or


offering previews of combined data. Formats like HAL
include ability to serve up _embedded data, letting you give
clients what they need. Spring Data REST does this through
projections, but you can use anything.

10
Straw man arguments against REST

In fact, server-side providers will probably have a better


insight into exactly the volume of traffic fetching such data
before clients. And through the power of hypermedia, can
evolve to add links to the hypermedia without breaking
existing clients. Old clients can do multiple hops; new clients
can proceed to consume the new links, with full backwards
compatibility.

Rest servces too much data

If you look closely, you’ll notice that our page


is using a movie’s title and image, and an
actor’s name and image (i.e. we are only
using 2 of 8 fields in a movie object and 2 of
7 fields in an actor object). That means we
are wasting roughly three-quarters of the
information that we are requesting over the
network! This excess bandwidth usage can
have very real impacts on performance as
well as your infrastructure costs!

Just a second ago, we complained that the REST API was


serving up too little data, forcing us to take multiple hops.
Now we are complaining that it serves too much data and is
wasting bandwidth.

The example in the article is a bit forced, given we are


probably talking a couple tweets worth of data. It’s not like
they are shipping 50MB too much. In fact, big volume data
(images, PDFs) would best be served as links in the

11
Straw man arguments against REST

hypermedia. This would let the browser efficiently fetch a


linked item once, and lean on the browser’s cache.

But I sense the real derision in the article is because the


endpoint isn’t tailored to the client’s precise demands. No,
the real example here is to illustrate a query technique on
the client.

Just put SQL in the client already!

Wouldn’t it be nice if we could build a


generic API that explicitly represents the
entities in our data model as well as the
relationships between those entities but that
does not suffer from the 1 + M + M +
sum(Am) performance problem? Good news!
We can!

With GraphQL, we can skip directly to the


optimal query and fetch all the info we need
and nothing more with a simple, intuitive
query.

So now we get to the real intent of the article: introduce a


query language. Presumably solving REST’s straw man
“problems” (which it doesn’t).

12
Straw man arguments against REST

If you want to write a highly detailed query, just open a


connection the data store and query directly. That’s what
query languages are for. Why invent something that’s
weblike, but really just Another Query Language?

What problem are you solving?

13
Straw man arguments against REST

GraphQL takes a fundamentally different


approach to APIs than REST. Instead of
relying on HTTP constructs like verbs and
URIs, it layers an intuitive query language
and powerful type system on top of our data.
The type system provides a strongly-typed
contract between the client and server, and
the query language provides a mechanism
that the client developer can use to
performantly fetch any data he or she might
need for any given page.

This query technology may be quite handy if you must write


intense, focused queries. If cutting a couple text-based
columns makes that much difference, then REST may not be
solution you seek. (Of course, at that point why not just have
your JavaScript frontend open a SQL/MongoDB/Neo4j
connection?)

What does REST solve? REST solves the brittle problem that
arose with CORBA and SOAP.

REST makes it possible to evolve APIs


without forcing you to update every client at
once.

Think about that. When web sites make updates, does the
web browser require an update? And why?

14
Straw man arguments against REST

It’s no light feat of accomplishment. People were being


beaten up left right as APIs would evolve. Updates were
tough. Some clients would get broken. And availability is key
for web scale business. So adopting the tactics that made the
web resilient into API design sounds like a keen idea to try.

Too bad not enough people actually know what these


concepts are, and press on to criticize REST while offering
“fixes” that don’t even address its fundamentals. The
solution served in the article would put strong domain
knowledge into the client, resulting in tight coupling. REST
doesn’t shoot for this.

Am I making this assessment up?

This “virtual graph” is more explicitly


expressed as a schema. A schema is a
collection of types, interfaces, enums, and
unions that make up your API’s data model.
GraphQL even includes a convenient schema
language that we can use to define our API.
(Emphasis mine)

Agreed. Continuing with more tight coupling instead of


letting server side logic remain server side would align with
SOAP 2.0, in my opinion. And it’s something I don’t much
care for.

We’ll dig in a little more about how REST makes it possible to


evolve APIs with minimal impact in the next chapter.

15
Straw man arguments against REST

16
What does REST really do?

2
What does REST really do?
In the previous chapter, I challenged someone’s proposal
that their client-side query language could supplant the
power of REST. It seemed to attack straw man arguments
about REST. In this chapter, let’s delve a little more into what
REST does and why it does it.

The Basis of REST

REST was created to take the concepts that made the web
successful, into API development. The success of the web,
which some people don’t realize, can be summarized like
this: “if the web page is updated, does the browser need an
update?”

No.

When we use RCP-oriented toolkits with high specificity, one


change can trigger a forced update to all parties. The clinical
term for this is “brittle“. And people hate brittleness. When
updates are being made, resources are no longer available.

Let’s take a quick peek at the banking industry. Despite what


you think, the banking industry isn’t built up on transactions
and ACID (Atomicity/Consistency/Isolation/Durability). Nope.
It’s built on BASE (Basic Availability/Soft-state/Eventual
consistency). An ATM machine can be disconnected from the
home office, yet it will dispense cash. You can go over your

17
What does REST really do?

limit, and still get money. But when things are made
consistent, it’s you that will be paying the cost of
overdrawing, not the bank.

When it comes to e-commerce, downtimes of


hours/minutes/seconds can translate into millions or billions
of lost dollars. (Hello, Amazon!)

Updating ALL the clients because you want to split your API’s
“name” field into “firstName” and “lastName” will be nixed
by management until you A) show that it doesn’t impact
business or B) prove the downtime to upgrade won’t cause
any loss of revenue.

Evolving an API

To evolve an API, we need to reduce breakages. We need to


be able to make changes to the API that will not impact
existing clients. Changes that allow existing clients to keep
right on humming as if nothing has happened.

Eventually, they can catch up and take advantage of the new

18
What does REST really do?

features. But only when they’re good and ready. And SOAP
and CORBA were not built for this. Their definition
languages (WSDL and IDL) don’t know how to be “flexible”.

But REST can. How? Let’s start with that example mentioned
earlier, a resource that serves up a name. Perhaps a small
piece of some e-commerce platform. You design this:

Example 1. Foo

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Customer {
private String name;
}

When an instance of this domain object is turned into a


hypermedia-based JSON structure (through a controller we
might construct), it would look like this:

Example 2. Foo

{
"name": "Frodo Baggins",
"_links": {
"self": {
"href": "/customers/1"
}
}
}

This nice bit of JSON flies around the system. You build

19
What does REST really do?

powerful clients leveraging its vast data. Customer growth is


exponential.

But suddenly, we’re victims of our own success. Your initial


take on a customer representation was kind of scratched
together. And now your manager darkens your door, saying,
“We need first and last name. Can you do that?”

You nod and get cracking. Just need to replace name with
firstName and lastName, and update all the clients. Except
what you just said will incur downtime. No, you need
something a little smoother. Something that can roll out and
not impact the existing clients. Instead of “versioning” your
API, why not ADD TO your existing resource?

Example 3. Foo

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Customer {

private String firstName;


private String lastName;

public void setName(String wholeName) {


String[] parts = wholeName.split(" ");
this.firstName = parts[0];
this.lastName = parts[1];
}

public String getName() {


return firstName + lastName;
}
}

Ta-dah!

20
What does REST really do?

Your updated domain object moves from having a single


name to a first and last name, as requested. But that is not
all. It also can generate that old name field, using the new
data. And it can parse an incoming “name” field, turning it
into your new ones.

What does this look like in JSON?

Example 4. Foo

{
"firstName": "Frodo",
"lastName": "Baggins",
"name": "Frodo Baggins",
"_links": {
"self": {
"href": "/customers/1"
}
}
}

You are now sporting both the new fields and the original
one. Old clients, if they follow the conventions of REST, will
simply ignore the new stuff and use the old stuff. If they
need to POST an update, they know where to send it and can
send just the fields they know. Your code can handle this!

Of course, you’ll have to migrate your data store before


rolling this out. But again, you can maintain availability with
just a little extra effort.

21
What does REST really do?

Honoring the robustness principle

Be conservative in what you do, be liberal in


what you accept from others.

This statement is known as the Robustness Principle. It’s


what we accomplish
using @JsonIgnoreProperties(ignoreUnknown=true). This
annotation tells Jackson to NOT blow up when we receive an
unrecognized property. Old servers can accept the new
format, until they have a chance to catch up. And old clients
can also talk to new servers thanks to our customized
setName(wholeName) method.

By carrying around this extra sliver of information (two


copies of a person’s name instead of one), we can save
millions of dollars when used at scale.

And this is a core piece of REST. By avoiding antiquated


concepts like versioned APIs (a requirement for CORBA and
SOAP), and instead making our REST resources backwards
compatible, we not only reduce downtime, we can make
maintenance easier on ourselves.

In the next chapter, we’ll dig into hypermedia and how it can
not only power the web, but your API as well. <<< :code:
../hacking-spring-boot-code :spring_boot_version: 2.3.0.M2

22
Getting the real message of REST out there

3
Getting the real message of REST
out there
In the previous chapter, I talked about how investing effort
in backward compatibility and having flexible settings, it’s
possible to avoid a lot of “API versioning”, something Roy
Fielding has decried. In this article, we’ll look more closely at
the depth and power of hypermedia.

How the web does it

Let’s remember that REST is about bringing the scaleable


power of the web to APIs. One of those classic features is
“Hey, go to XYZ.com, click on ‘Books’, then click on ‘Fiction’,
then click on ‘The Job’ and you can get a free copy.”

Recognize this pattern? No one can remember long URLs, but


we all know about following a chain of menu items based on
the shorthand text.

Hypermedia is providing links all along the way. We


sometimes refer to this as a “discoverable” API. I once
likened it to the classic ZORK text adventure, where you have
a confined set of moves, yet can explore a very complex
world.

When clients hard code URLs, updates become brittle.


Everyone knows this, otherwise there wouldn’t be things like
a CORBA Naming Service subspec. So when I see tools that

23
Getting the real message of REST out there

not only support but advocate full focus on URIs, I cringe.


This isn’t what REST is about.

It really is aimed at following a chain of links. Because that


grants us an incredible power to migrate services.

Imagine we had started things out with a service used to


manage supervisors. It was basic, perhaps a tad crude.
Maybe we were wet behind the ears and didn’t totally grok
REST. Not a lot of hypermedia. But eventually, we migrated to
a newer “manager” service.

The good news with hypermedia is that we can continue to


serve data at the old URI:

{
"id": 1,
"name": "Gandalf",
"employees": [
"Frodo::ring bearer",
"Bilbo::burglar"
],
"_links": {
"self": {
"href": "http://localhost:8080/managers/1"
},
"managers": {
"href": "http://localhost:8080/managers"
},
"employees": {
"href": "http://localhost:8080/managers/1/employees"
}
}
}

If this fragment was served under the old URI, /supervisors/1,

24
Getting the real message of REST out there

old clients could access the data found there. But with a push
toward hypermedia consumption, they could navigate onto
the newer version of things.

This legacy representation can be put together by the newer


“manager” service to support the old clients.

@GetMapping(value = "/supervisors/{id}",
produces = MediaTypes.HAL_JSON_VALUE)
ResponseEntity<EntityModel<Supervisor>> findOne(
@PathVariable Long id) {

EntityModel<Manager> managerModel =
controller.findOne(id).getBody();

EntityModel<Supervisor> supervisorModel = EntityModel.of(


new Supervisor(managerModel.getContent()),
managerModel.getLinks());

return ResponseEntity.ok(supervisorModel);
}

This route, served to the old URI by the “manager” service,


can actually retrieve information in the newer format, and
repackage it as a legacy “Supervisor” record. But by
supplying up-to-date links, we provide an on-ramp for clients
to migrate.

Assuming we had shutdown the old “supervisor” service, the


following DTO could nicely sustain the old clients until they
were ready to move on up.

25
Getting the real message of REST out there

@Value
@JsonPropertyOrder({"id", "name", "employees"})
class Supervisor {

@JsonIgnore
private final Manager manager;

public Long getId() {


return this.manager.getId();
}

public String getName() {


return this.manager.getName();
}

public List<String> getEmployees() {


return manager.getEmployees().stream()
.map(employee ->
employee.getName() + "::" + employee.getRole())
.collect(Collectors.toList());
}
}

This immutable value type can take the new-and-improved


“manager” object and extract the older representation
smoothly.

Don’t argue the wrong end of things

I’ve seen a particular argument pop up in favor of REST


many times. It brags about how links can change without
impacting clients. Frankly, that argument comes across as
lame and weak. That’s because it’s NEVER presented under
the guise of backward compatibility. It’s kind of posed in a
vacuum.

26
Getting the real message of REST out there

Building REST resources with full focus on backward


compatibility, supporting old URIs and old formats, is a much
stronger message in my book.

SOAP and CORBA weren’t designed to let you slip in an extra


field here and there. At least, not without massive effort. It’s
why no one ever did. Can you imagine going into an
IDL/WSDL file and attempting to “slip in” an extra field to
ease migration? It’s almost incomprehensible.

But with Jackson and robust principles applied, it’s easy to


update a given route with additionaldata that can easily
support two different clients. One REST resource supporting
two clients: THAT is a strong argument. Not “links can
change”.

Don’t preach it, use it

It’s why I’m giving you a sneak peek at something I’ve been
wanting to write for about three months. I find myself
attempting to explain the same concepts about REST on
Twitter, at meetups. In Berlin, I ran into a dear friend that
pinned me down and asked me hard questions on REST for
over an hour. Bring it on! That affirmed my gut decision to
create this:

Spring HATEOAS Examples [https://github.com/spring-projects/


spring-hateoas-examples]

This repository contains several REST-based scenarios and


how to implement them with Spring HATEOAS. It’s not
complete. It hasn’t even been “publicly” announced, but it
gives me a concentrated place to show how REST works

27
Getting the real message of REST out there

compared to RPC-over-HTTP.

The numerous times I’ve watched Oliver defend REST, I too


and picking up the banner and striving to help spread the
word that if we can adopt HATEOAS and link-driven flows,
we can build more sustainable systems.

For a little something to chew on, I’ll close this article with
the following tweet.

I strongly encourage you to click through [https://twitter.com/


odrotbohm/status/458578827342794752], and read the follow on
conversation as people blink in shock “What’s wrong with
Swagger?”

If you are interested in more, stay tuned. Currently in the


works is Hacking with Spring Boot 2.3: Classic Edition. Not
everything requires the highly scalable, Reactive Streams
solution. Classic Spring Boot packs a punch and lets you
continue using technologies you know and love including
JPA, servlets, and more.

28
Getting the real message of REST out there

Join my email list at GregLTurnquist.com/hacking-with-


spring-boot-fan and stay tuned as that develops (and catch
my technical newsletter).

In case you want to dive even deeper into Spring’s reactive


story, check out Reactive Spring [https://leanpub.com/reactive-
spring] by globe-trotting developer advocate Josh Long.

Don’t forget to subscribe to my YouTube channel at


YouTube.com/GregTurnquist and hear more about Spring
Boot.

Thanks,
Greg "Spring Boot hacker" Turnquist

29
Getting the real message of REST out there

30
About the Author
Greg L. Turnquist works on the Spring team as a principal
developer at VMware. He is a committer to Spring HATEOAS,
Spring Data, Spring Boot, R2DBC, and Spring Session for
MongoDB. He founded the Nashville JUG in 2010 and hasn’t
met a Java app (yet) that he doesn’t like.

To catch all of Greg’s future works, signup at


http://greglturnquist.com/hacking-with-spring-boot-fan.
You’ll get a free technical handout as a bonus!

Follow him on Twitter @gregturn and subscribe for all his


Spring Boot videos at YouTube.com/GregTurnquist.

Also enjoy his other published works, technical as well as


fiction:

Technical
Hacking with Spring Boot 2.3: Reactive Edition
Learning Spring Boot 2.0 2nd Edition
Learning Spring Boot [Video]
Learning Spring Boot
Python Testing Cookbook
Spring Python 1.1

Fiction
Darklight
The Job: A Darklight Chronicle

31

You might also like