So it's clear for me what idempotence means based on this Defining Idempotence
But I also heard a lot people describe such behavior as deduping. Is that an equivalent terminology?
For example, if an API is idempotent that same request being processed for N times will get the state same as one time. Can I say that API is deduping requests?
The two terms are not equivalent, though it may be helpful for people unfamiliar with idempotency to think of it initially based on its similarity to deduplication.
For a contrasting example, consider an API for a bank account which accepts a positive or negative number by which to adjust the account balance (deposit or withdrawal). Clearly this API is not idempotent, because consecutive transactions have a cumulative effect.
On the other hand, we would certainly want to deduplicate these transactions. If transaction #123 is (erroneously) submitted twice, it should apply to the account balance only once. In this case, transactions should be deduplicated because the API is not idempotent.
Deduplication is an activity: an action to perform. Idempotency is an attribute: a property to describe. A similarity exists between the two when the result of deduplication is the same as the effect of idempotency; that is, no change in state. But an equivalent outcome does not make the two terms equivalent.
Related
I'm currently evaluating using Plaid or Yodlee for transaction aggregation (I'm using the Dev environments for both right now). I really prefer almost everything about Plaid, but I'm having trouble with transaction name/description. Yodlee has a data field called the "simple description":
From their docs: "The transaction description that appears at the FI site may not be self-explanatory, i.e., the source, purpose of the transaction may not be evident. Yodlee attempts to simplify and make the transaction meaningful to the consumer, and this simplified transaction description is provided in the simple description field."
I'm displaying the transaction name to my end-users and I'm looking for something more user friendly than the transaction name field which often returns strings like "Withdrawal Check Card MOE'S BROADWAY BAGE BOULDER CO Date 01/06/19 0 9006020339 0 5812 Card [XXXX]".
I'm sure I'm not the first plaid customer to have this need. How do Plaid reliant apps solve this problem?
Plaid doesn't offer a simple description field as far as I know, but they do clean up transaction names.
I've found that when a new pending transaction comes in, the name is messy like you mention (e.g. UBER *TRIP 5VVB2). But once the transaction is confirmed, Plaid normalizes it for common merchants (e.g. Uber). I don't know why Plaid doesn't offer this normalization for pending transactions, but I have brought it up with them before. Perhaps this is something that could change in the future?
A solution, albeit complicated, is to build a custom model that normalizes transaction names. That's what we are doing at Pluto Money to supplement Plaid's transaction data.
I received a direct response by email from Plaid Support:
Thanks for reaching out to us here on Plaid Support, I'm sorry about
our delay.
Our name field for each transaction represents our best effort to
balance detailed transaction information while providing a clean and
consistent API response. This behavior does vary across banks, both
due to bank behavior and our own integration quality. Generally at
larger banks our integrations do a better job at returning clean
transaction names with appropriate transaction detail but for some of
our smaller banks transaction names may be more "raw".
If you never want additional detail beyond the merchant/transaction
name in your app I would encourage you to implement some filtering on
Plaid's name field to make sure that no date- or account number-like
character strings pass through into your user facing stream.
I am working on an application which requires some double entry bookkeeping. Currently there are two endpoints
/account
/transaction
While /account handles general data of the accounts, /transaction handles transactions for deposits/withdrawal. Account balance is calculated based on the related transactions. I kept them separated to get consistency in the bookkeeping when transferring value from one to another account.
My question is how to represent the balance of an account at the /account endpoint as it always will be calculated on request time. Should a response just contain the balance as a read-only field? This smells like bad API design since all fields but this one would be writeable/updateable.
The alternative coming to my mind would be to extend the endpoint to
/account/{id}/balance
returning only the balance of the regarding account. However, this would always require a second call to get the balance in addition to the remaining data of the account. Maybe the answer could generalized on how to represent aggregated values.
Very good question. I run into situations like this, often. I would say two things:
You probably have other "read-only" fields, like "id"
You may not want to incur the time it takes to calculate the current balance every time you get an account details.
I think I would opt for /account/{id}/balance ... but maybe name it /account/{id}/calculatebalance to indicate that it does take some time to run this methods. And, then it is obvious that the value is a calculated value. If you had "several" calculated values, then I would rethink my opinion.
2 cents.
You usually don't write aggregate properties, so it is natural that the property is read only. It is a sing that you are starting to have a service instead of a database with HTTP interface. Recalculating for each request is not necessary if you can cache it somewhere, though it depends on your needs. I see this is a very old question, idk. how I clicked on it.
I've been using Gherkin (with Cucumber) for many years now. I noticed early on that Cucumber.io homepage examples refer to 'I' in the given and when statements, but not in the then statements.
I always assumed this was because given and when statements are subjective actions by a user, where as then statements should be objective measures about the state of the application under test.
However, I noticed in the official Cucumber book, their examples refer to 'I' all the way through the steps (including when using then statements).
Anyone know which method is correct?
In my experience regarding the BDD and Gherkinri, we've always considered that the User story has two actors: User and System. Not all actors are end users. For example, a role could be another system or someone who wants certain functionality in order to buy your product but will never actually use the product. It may be useful to create aggregate roles (such as consumer) and specialized roles (such as browser or frequent shopper). So having I in the Then steps is actually expected result from end-user's perspective. Example:
Then I should see that cash amount 'storedTotalAmount' and cash amount 'currentAmount' are equal 'true'
There is not a definitive rule as to whether "Then" statements should include "I". As #ekostadinov it depends on the Actors which are taking part in the test scenario.
For instance in a messaging scenario:
Given Alice is on a messaging page
When Alice posts a message to Bob
Then Bob should receive the message
In such a scenario it would make no sense to use "I" in the "Then". However if you had a slightly different scenario:
Given I am on the messaging page
When I post a message to Bob
Then I should receive confirmation that Bob received the message
Then using "I" does make sense.
Hence it depends on how you write your tests. To conclude, I prefer to use personas (i.e. particular types of users in your system) throughout my tests e.g. Alice, Bob etc. This generally removes any possible ambiguity with the use of "I".
We are creating api on employee manage app. So there is schedule in interface, where we have to show all shifts in table, for every user per row. Farther, there is summary for every user (per row) and day (per column). Should we create one big aggregate call like:
GET /api/locations/{id}/shedule
which will return all employees, shifts, summaries etc. Or maybe should we smash that to several collections like:
GET /api/locations/{id}/shifts
GET /api/locations/{id}/events
GET /api/locations/{id}/summary
GET /api/employee/{id}/summary?date_from={date_from}&date_from={date_to}
For me, second option is more flexible and there is no reason to create new abstract resource, which is shedule. In my opinion it is clearly part of interface layer and should not affect on API design.
On the other hand the big aggregate is more optimal, becouse there will be less database calls and it's easy to cache.
How do you think? Is there any source, kind of article, which can I rely on?
There's nothing RESTful or unRESTful about either approach. The semantics of URIs is irrelevant to REST. What really matters is how the clients obtain the URIs. If they are looking up URI patterns in documentation and filling up values instead of using links, the API is not RESTful.
With that in mind, I'd say the approach that is more consistent with your business and your ecosystem of applications is the best one. Don't be afraid to create aggregate resources if you feel the need to.
Currently I am developing an API and within that API I want the signed in users to be able to like/unlike or favorite/unfavorite two resources.
My "Like" model (it's a Ruby on Rails 3 application) is polymorphic and belongs to two different resources:
/api/v1/resource-a/:id/likes
and
/api/v1/resource-a/:resource_a_id/resource-b/:id/likes
The thing is: I am in doubt what way to choose to make my resources as RESTful as possible. I already tried the next two ways to implement like/unlike structure in my URL's:
Case A: (like/unlike being the member of the "resource")
PUT /api/v1/resource/:id/like maps to Api::V1::ResourceController#like
PUT /api/v1/resource/:id/unlike maps to Api::V1::ResourceController#unlike
and case B: ("likes" is a resource on it's own)
POST /api/v1/resource/:id/likes maps to Api::V1::LikesController#create
DELETE /api/v1/resource/:id/likes maps to Api::V1::LikesController#destroy
In both cases I already have a user session, so I don't have to mention the id of the corresponding "like"-record when deleting/"unliking".
I would like to know how you guys have implemented such cases!
Update April 15th, 2011: With "session" I mean HTTP Basic Authentication header being sent with each request and providing encrypted username:password combination.
I think the fact that you're maintaining application state on the server (user session that contains the user id) is one of the problems here. It's making this a lot more difficult than it needs to be and it's breaking a REST's statelessness constraint.
In Case A, you've given URIs to operations, which again is not RESTful. URIs identify resources and state transitions should be performed using a uniform interface that is common to all resources. I think Case B is a lot better in this respect.
So, with these two things in mind, I'd propose something like:
PUT /api/v1/resource/:id/likes/:userid
DELETE /api/v1/resource/:id/likes/:userid
We also have the added benefit that a user can only register one 'Like' (they can repeat that 'Like' as many times as they like, and since the PUT is idempotent it has the same result no matter how many times it's performed). DELETE is also idempotent, so if an 'Unlike' operation is repeated many times for some reason then the system remains in a consistent state. Of course you can implement POST in this way, but if we use PUT and DELETE we can see that the rules associated with these verbs seem to fit our use-case really well.
I can also imagine another useful request:
GET /api/v1/resource/:id/likes/:userid
That would return details of a 'Like', such as the date it was made or the ordinal (i.e. 'This was the 50th like!').
case B is better, and here have a good sample from GitHub API.
Star a repo
PUT /user/starred/:owner/:repo
Unstar a repo
DELETE /user/starred/:owner/:repo
You are in effect defining a "like" resource, a fact that a user resource likes some other resource in your system. So in REST, you'll need to pick a resource name scheme that uniquely identifies this fact. I'd suggest (using songs as the example):
/like/user/{user-id}/song/{song-id}
Then PUT establishes a liking, and DELETE removes it. GET of course finds out if someone likes a particular song. And you could define GET /like/user/{user-id} to see a list of the songs a particular user likes, and GET /like/song/{song-id} to see a list of the users who like a particular song.
If you assume the user name is established by the existing session, as #joelittlejohn points out, and is not part of the like resource name, then you're violating REST's statelessness constraint and you lose some very important advantages. For instance, a user can only get their own likes, not their friends' likes. Also, it breaks HTTP caching, because one user's likes are indistinguishable from another's.