DZone
Integration Zone
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
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Integration Zone > 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.

Hany Ahmed user avatar by
Hany Ahmed
·
Jan. 14, 22 · Integration Zone · Analysis
Like (8)
Save
Tweet
5.32K 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.

Popular on DZone

  • Kafka Fail-Over Using Quarkus Reactive Messaging
  • Image Classification Using SingleStore DB, Keras, and Tensorflow
  • Message Queuing and the Database: Solving the Dual Write Problem
  • Transactions vs. Analytics in Apache Kafka

Comments

Integration Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo