Yurii Shylov
Yurii Shylov

Reputation: 1217

How to implement action invocation in RESTful way?

I have a server which operates with two resources - groups and users. Both of them may be either local or ldap. The server should be able to take users and their membership from external LDAP server and put them into internal storage. It is also required to be able to omit some users from synchronization.

I see two more or less good ways to implement this:

  1. Create resource sync_request by POST. It will be created with an array ldap_users and flag confirmed=false. After marking the required users, send updated list and confirmed=true with PUT.
  2. Create singleton resource sync_controller. It contains two arrays: ldap_users and local_users, both are retrieved by GET. Whenever you want to sync users, you take several of them from the list ldap_users and put them to local_users, than update the controller with PUT.

The drawback of both approaches is that in fact they modify users and groups resources. Also the GET request in #2 is not idempotent as ldap_users will be retrieved in every request and thus the list will be changed every time.

Is there any elegant way to implement this functionality? If not, which approach is better?

Upvotes: 0

Views: 76

Answers (1)

Eric Stein
Eric Stein

Reputation: 13702

I don't think idempotence means what you think it means. It refers to the side effects of a request. It does not guarantee that the resources will never change. If it did, you'd never be able to update anything that you could GET.

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.
     -- HTTP RFC 7231

I'm not really sure why you'd need to create an incomplete request. Assuming that there's no business requirement to do so, I would consider attacking the problem like this:

GET /users?type=ldap
{
    "count": 3,
    "users": [ 
        { "id": "bob" }, 
        { "id": "mary" }, 
        { "id": "joran" }
    ]
}
POST /sync_requests
{
    "users": ['bob', 'mary']
}

GET /sync_requests/234
{
    "status": "successful",
    "users": ['bob', 'mary']
}

Upvotes: 1

Related Questions