DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • GraphQL vs REST API: Which Is Better for Your Project in 2025?
  • Building a REST Service That Collects HTML Form Data Using Netbeans, Jersey, Apache Tomcat, and Java
  • Spring Boot - How To Use Native SQL Queries | Restful Web Services
  • Testing REST Controller Methods With JUnit 5 [Video]

Trending

  • A Hands-On ABAP RESTful Programming Model Guide
  • How to Format Articles for DZone
  • What Is Plagiarism? How to Avoid It and Cite Sources
  • AI Paradigm Shift: Analytics Without SQL
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. An Analysis on Designing Action-Based REST APIs

An Analysis on Designing Action-Based REST APIs

Designing action-based REST APIs for CRUD operations has a simple solution, whereas designing for non-CRUD operations is not as simple.

By 
Hany Ahmed user avatar
Hany Ahmed
·
Jan. 14, 22 · Analysis
Likes (8)
Comment
Save
Tweet
Share
6.4K Views

Join the DZone community and get the full member experience.

Join For Free

SOAP is based on operations that are mapped easily to a normal function in code. REST, on the other hand, deals with resources that should be mapped somehow to functions.

HTTP
 
Code			| SOAP				| REST
getUsers()		| getUsers			| !
addUser(..)		| addUser			| !
UpdateUser(..)		| updateUser			| !
deleteUser(..)		| deleteUser			| !

REST is not a protocol itself; it depends only on what HTTP provides. Therefore, HTTP should provide us with a solution to do/ask for something.

CRUD Actions

Luckily, we have functions in HTTP request standard called HTTP methods, and it fits in normal CRUD operations:

  • GET for Read
  • POST for Create
  • PUT for Update
  • DELETE for (guess what?) Delete

Suppose we want to provide some APIs to manage users. We may have APIs like the following:

  • GET /users to get all users
  • POST /users to add a new user (user details in the body)
  • PUT /users/{userId} to update a specific user (user details in the body)
  • DELETE /users/{userId} to delete a user

Non-CRUD Actions

HTTP is sufficient to that point, but what if we want to provide an API for activating or deactivating users? Unfortunately, HTTP doesn't have ACTIVATE and DEACTIVATE methods. Here's what we can do:

1. Expose a Property

In this way we may expose a property like status (even if you don't have such a property):

HTTP
 
PUT /users/{userId}/status
ACTIVE

We may call this API passing a value in the body active/inactive to activate or deactivate the user.

2. Use PATCH

Unlike PUT which does a full update/replace, HTTP has another method called PATCH which does a partial update to one or more properties.

Even if you don't have a property for your action, your API may act like it has such one.

By having this API, you may send a partial update to only the status property

HTTP
 
PATCH /users/{userId}
{
    "status": "active"
}

3. Think About a Sub-Resource

We may invent a resource that handles this operation.

In our example, we have a user's sub-resource called active and we can locate it using the path /users/{userId}/active

and provide API for each action:

POST /users/{userId}/active to activate the user

DELETE /users/{userId}/active to deactivate the user

Pure Action

There are some actions that are not related to a property in an object or not persisted to a database, for example, a service that calculates something.

Another example is a function that calculates the square root of a number, rather than designing it like this:

POST /calculateSquareRoot?number={number}

It can be designed like this:

GET /square-roots/number

Note that also we converted it to a GET as the result is not changing, so it'd be a good idea to make it idempotent and safe, so it may be cached.

4. A Verb in the URI

One of the rules of REST is to depend on resources, So you shouldn't put verbs in your URIs.

Rules are made to be broken, choosing a verb may be more simple and better than other solutions.

 Look at this:

POST /users/{userId}/activate to activate the user

POST /users/{userId}/deactivate to deactivate the user

For example:

  • POST /users/{userId}/drafts/send and POST /users/{userId}/messages/{id}/trash in gmail API
  • POST /videos/rate in youtube API
  • POST /v1/payments/sale/{sale_id}/refund in paypal API
REST Web Protocols

Opinions expressed by DZone contributors are their own.

Related

  • GraphQL vs REST API: Which Is Better for Your Project in 2025?
  • Building a REST Service That Collects HTML Form Data Using Netbeans, Jersey, Apache Tomcat, and Java
  • Spring Boot - How To Use Native SQL Queries | Restful Web Services
  • Testing REST Controller Methods With JUnit 5 [Video]

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook