The History of REST APIs
9 min read
Dom Harrington

Open Source Engineer

The History of REST APIs

In 1999, the API environment was a free-for-all.

At that point, most developers had to deal with SOAP (Simple Object Access Protocol) to integrate APIs. And the “simple” part of that acronym is not to be taken literally. To make a call, they had to hand-write an XML document with an RPC call in the body. From there, they had to specify the endpoint and POST their SOAP envelope to that specified endpoint.

A super simple SOAP API request looks something like this:

<?xml version="1.0"?>
<SOAP:Envelope
    xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance"
    xmlns:xsd="http://www.w3.org/1999/XMLSchema"
    xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
    <SOAP:Body>
        <calculateArea>
            <origin>
                <x xsd:type="float">10</x>
                <y xsd:type="float">20</y>
            </origin>
            <corner>
                <x xsd:type="float">100</x>
                <y xsd:type="float">200</y>
            </corner>
        </calculateArea>
    </SOAP:Body>
</SOAP:Envelope>

If it looks nonsensical to you, it should. All of this is put together to meet an arbitrary set of guidelines specified in the documentation, which explains the transport bindings, types of data that can be accessed, parameter lists, operation names, and the endpoint URI. And if the call doesn’t work, there aren’t any HTTP respond codes to nudge you in the right direction.

SOAP was notorious for being complex to build, complex to use, and near-impossible to debug. And the alternative, CORBA, was even worse. The problem was that there was no standard for how APIs should be designed and used. Back then, APIs were not designed to be accessible, they were only designed to be flexible.

But a small group of expert developers recognized the true potential of web APIs. Thanks to this small group, led by Roy Fielding, REST was coined and the API landscape changed forever.

Here’s how it all went down:

The birth of REST: Roy Fielding’s dissertation

In 2000, Roy Fielding and his colleagues had one objective: Create a standard, so any server could talk to any other server in the world. Here’s what he came up with in his doctoral dissertation:

I had comments from well over 500 developers, many of whom were distinguished engineers with decades of experience, and I had to explain everything from the most abstract notions of Web interaction to the finest details of HTTP syntax. That process honed my model down to a core set of principles, properties, and constraints that are now called REST.

  • Uniform interface. This means we always use HTTP verbs (GET, PUT, POST, DELETE). We always use URIs as our resources. And we always get an HTTP response with a status and a body.
  • Stateless. This means each request is self-descriptive, and has enough context for the server to process that message.
  • Client-server. There has to be clear boundaries between roles of the two two systems. One server, operationally, has to function as the server that is being called, and the other has to function as the one making the requests.
  • Cacheable. Unless denoted, a client can cache any representation. This is possible thanks to the statelessness—every representation is self-descriptive.

Another important difference between REST and SOAP is that it’s resource-based. That means the API accesses nouns (aka URIs), instead of verbs. Then, HTTP verbs are used to access those resources.

It seems like there are a lot of rules, but those rules are universal. It forces the API to be simpler, and makes the learning curve for developers trying to integrate software significantly less steep. Roy Fielding gave the disorganized internet world the gift of a common language through which their software could communicate.

Modern REST API principles for today’s developers

Since Roy Fielding introduced REST in his 2000 dissertation, REST APIs have become the backbone of web communication, offering a simpler alternative to protocols like SOAP. Their stateless nature and use of standard HTTP methods have made them integral to web and mobile applications.

Let’s take a closer look at the six guiding principles of REST API design:

1. Uniform interface

The uniform interface principle ensures a standardized method of communication between the client and server, simplifying interactions and decoupling the architecture. This standardization allows different clients to interact with the server in a consistent manner, improving interoperability and reducing complexity.

For example, using standard HTTP methods like GET, POST, PUT, and DELETE across all resources ensures that clients can predictably interact with the API. This predictability reduces the learning curve for developers and promotes a more intuitive integration process.

2. Statelessness

In a stateless system, each client request is self-contained, carrying all necessary information for the server to process it. This means the server doesn’t store any session data between requests, allowing it to handle each one independently. This design enhances scalability, as servers aren’t burdened with maintaining session information.

For example, in RESTful APIs, when a client requests user data, it includes authentication credentials within that request. The server then processes the request based solely on this information, ensuring each interaction is isolated and efficient.

3. Cacheability

Cacheability lets servers mark responses as cacheable or non-cacheable, allowing clients to store and reuse them for future requests. This boosts performance by reducing repeated server processing and lowers latency for users.

For instance, a server can include cache-control headers in its responses to specify whether data can be cached and for how long. Clients can then store this data and use it for subsequent requests, easing the server’s load and delivering quicker responses to users.

4. Client-server separation

This principle emphasizes a clear divide between the client and server, enabling each to evolve independently as long as their interface remains consistent. Such separation enhances flexibility and scalability—changes on the server don’t impact the client, and vice versa.

For example, a mobile app (client) can interact with a cloud-based database (server) through a defined API. The server can undergo maintenance or upgrades without requiring changes to the client app, provided the API stays consistent.

5. Layered System

A layered system architecture structures an API into hierarchical layers, with each layer aware only of its immediate interactions. This design enhances scalability and manageability, allowing layers to be developed and updated independently.

For example, an API might include:

  • A presentation layer handling HTTP requests.
  • A business logic layer processing data.
  • A data access layer interacting with the database.

Each layer operates independently, promoting modularity and ease of maintenance.

6. Code on demand (optional)

The code on demand principle allows servers to temporarily extend or customize client functionality by transferring executable code, like JavaScript. This optional feature can enhance client capabilities without requiring a full software update.

For instance, a server might send a JavaScript function to the client to process data locally, reducing the need for additional server requests and enabling more dynamic interactions.

By following these principles, developers can create RESTful APIs that are robust, scalable, and easy to maintain—providing a solid foundation for web services that effectively meet user needs.

Learning to make money from an API

Salesforce was technically the first company to sell an API as part of their “internet as a service” package in 2000, but few developer teams were able to take advantage of its complicated XML API, equipped with a 400+ page PDF manual.

eBay, on the other hand, built a REST API, and has shown the world just how lucrative an accessible API can be. Seeing what Salesforce was up to, eBay jumped on the opportunity to give select partners access to its relatively easy-to-use API, equipped with thorough online documentation.

Screenshot of Wall Street Journey headline announcing eBay's goal to be the operating system for all e-commerce on the internet

When eBay first launched its API, the Wall Street Journal wrote: “eBay’s new technology—with the decidedly uncatchy name of eBay API (for eBay application programming interface)—reflects the company’s growing belief that it can get a piece of e-commerce beyond the confines of its popular online trading post at eBay.com.” eBay’s market was no longer limited to the people coming to its website. It extended to any site that could access their API.

The value of extending an e-commerce product offering to other sites is obvious—more opportunities to sell their stuff. And because the implementation of their API was simple and according to the RESTful standard, lots of sites were quick to jump on the opportunity. After all, it enabled them to expand the product offering to their own customers.

It didn’t take long for Amazon to follow in eBay’s footsteps.

Screenshot of 2002 press release announcing Amazon's web services

Most importantly, these e-commerce giants nudged other online platforms to start thinking about the value of their code, not just their consumer-facing product.

Pros & Cons of REST APIs

REST APIs are like the Swiss Army knives of web services—they’re versatile, easy to use, and have become a go-to for many developers. They let different software systems chat with each other over HTTP, making integration a breeze. Plus, they’re pretty straightforward to set up and play nicely with various data formats like JSON and XML. The tradeoff for convenience is that REST APIs can sometimes be a bity chatty, leading to slower performance, especially when you’re juggling a lot of data.

ProsCons
Simple and easy to useCan be less efficient with large data volumes
Stateless operations enhance scalabilityLack of strict standards can lead to inconsistencies
Wide adoption and support across platformsOverhead due to multiple requests for complex data
Flexibility with data formats (JSON, XML)Limited support for real-time communication

Managing the challenges of REST APIs

Managing REST APIs effectively requires addressing several key challenges to ensure their robustness and reliability.

Versioning

An API versioning strategy is an absolute must-have to maintain backward compatibility and support new features. Common versioning methods include:

  • URI path versioning. Incorporating the version number directly into the URL (e.g., /api/v1/resource). This approach is straightforward but can lead to cluttered URLs.
  • Query parameter versioning. Adding the version as a query parameter (e.g., /api/resource?version=1). While this keeps URLs cleaner, it may complicate routing logic.
  • Header versioning. Specifying the version in request headers (e.g., Accept-Version: 1.0). This method maintains clean URLs but can be more complex to implement and test.

Choosing the best versioning strategy depends on factors such as API complexity, client needs, and the desired level of control over version management.

Endpoint consensus and consistency

Achieving consensus on REST endpoint design is vital for API usability and maintainability. Common errors and challenges include inconsistent naming conventions, resource modeling, versioning, maintaining a clear hierarchy for nested resources.

Here’s an example demonstrating how to achieve consensus on REST endpoint design. This example follows best practices for naming conventions, resource hierarchy, and consistent HTTP methods, making the API intuitive and developer-friendly.

Scenario: Building a REST API for managing books and authors

const express = require('express');
const app = express();
app.use(express.json());

// Example data
const books = [
  { id: 1, title: "The Great Gatsby", authorId: 1 },
  { id: 2, title: "To Kill a Mockingbird", authorId: 2 },
];
const authors = [
  { id: 1, name: "F. Scott Fitzgerald" },
  { id: 2, name: "Harper Lee" },
];

// REST Endpoints

// Get all books
app.get('/api/books', (req, res) => {
  res.json(books);
});

// Get a single book by ID
app.get('/api/books/:id', (req, res) => {
  const book = books.find(b => b.id === parseInt(req.params.id));
  if (!book) return res.status(404).send('Book not found');
  res.json(book);
});

// Create a new book
app.post('/api/books', (req, res) => {
  const newBook = {
    id: books.length + 1,
    title: req.body.title,
    authorId: req.body.authorId,
  };
  books.push(newBook);
  res.status(201).json(newBook);
});

// Update a book
app.put('/api/books/:id', (req, res) => {
  const book = books.find(b => b.id === parseInt(req.params.id));
  if (!book) return res.status(404).send('Book not found');
  book.title = req.body.title || book.title;
  res.json(book);
});

// Delete a book
app.delete('/api/books/:id', (req, res) => {
  const index = books.findIndex(b => b.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).send('Book not found');
  books.splice(index, 1);
  res.status(204).send();
});

// Nested resource: Get books by a specific author
app.get('/api/authors/:authorId/books', (req, res) => {
  const authorBooks = books.filter(b => b.authorId === parseInt(req.params.authorId));
  res.json(authorBooks);
});

// Start the server
const PORT = 3000;
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));

The API design ensures consistency by using plural nouns for resource endpoints (e.g., /api/books, /api/authors), aligning endpoint behaviors with HTTP methods, and maintaining clear resource hierarchies through nested resources like /api/authors/:authorId/books.

It also employs meaningful HTTP status codes (e.g., 404 for not found, 201 for resource creation) and is scalable, allowing easy addition of new resources or features like filtering and sorting.

And it goes without saying that implementing comprehensive API documentation can mitigate these challenges.

Handling multiple requests and data management

REST APIs must efficiently manage multiple, potentially concurrent requests to maintain performance and data integrity. Challenges include:

  • Concurrency control. Simultaneous requests modifying the same resource can lead to data inconsistencies. Implementing synchronization mechanisms, such as locks or mutexes, can help manage concurrent access.
  • Idempotency. Ensuring that repeated identical requests produce the same result is crucial, especially for operations like PUT and DELETE. Designing idempotent endpoints prevents unintended side effects from duplicate requests.
  • Rate limiting. High volumes of requests can overwhelm the API, leading to degraded performance. Implementing rate limiting controls the number of requests a client can make within a time frame, protecting the API from abuse.
  • Batch processing. Handling large datasets through multiple requests can be inefficient. Providing batch endpoints allows clients to submit multiple operations in a single request, improving efficiency.

The API economy and beyond

REST APIs are the backbone of the internet and as such powerful drivers, create huge new business opportunities. A website can only reach a small portion of your audience, but an API can extend your brand’s reach far beyond what even the original designers envisioned.

Today, APIs aren’t just a development technique. The creation of REST as a standard has led APIs to be used by far more people to accomplish far greater undertakings. They’re often a core part of software companies’ business models and, sometimes, are even the product itself.

Whether you’re embedding photos, tweeting, or storing five terabytes of data on the cloud, you’re constantly taking advantage of a landscape made possible by RESTful APIs.

For the end user, this means life is constantly getting easier. It’s easier to share documents at work, look up directions, call a taxi, and find old friends. For the developer, it means the sky’s the limit. Thanks to the evolution of REST APIs, we don’t need a team of engineers or thousand-dollar servers to build software anymore. As long as you can get an API key and access to documentation, you can integrate a functionality into your software.

Now just imagine how much could be possible if we could nail down a documentation standard!