Differentiate messages within same status code from web api - rest

I am developing a web API which will return Forbidden http status for multiple reasons-
User is blocked.
IP is blocked.
Request limit exceeded.
User is unverified.
I am returning response in following way-
return Content(HttpStatusCode.Forbidden, message); //message : "Limit reached" etc.
Now, I need to handle these reasons differently at client. Should I identify the reason from returned message? This message is to be displayed to user and might change in future.
What is the best practice for this?

What is the best practice for this?
Rather than trying to invent a schema of your own, you should probably look for something standardized, like Problem Details for HTTP APIs.
Problem Details describes a human readable "title" and "detail" field, and a "type" that is a link to human readable documentation.
Consumers MUST use the "type" string as the primary identifier for the problem type; the "title" string is advisory and included only for users who are not aware of the semantics of the URI and do not have the ability to discover them (e.g., offline log analysis). Consumers SHOULD NOT automatically dereference the type URI.
Consumers SHOULD NOT parse the "detail" member for information; extensions are more suitable and less error-prone ways to obtain such information.

Your error message should be descriptive for your client. Ideally you need to include the following information:
developers message (technical description - "cache is out-of-date", "service A is unavailable")
human-readable message (business description - "this time is booked already", "company A is closed and cannot be modified")
hint how to solve ("refresh your cache", "try again in 5 minutes", "request permission A from administrator")
href to your online documentation
Header like "error_code: 100". A custom code should also be described in the documentation. This one you may rely on in your client's code and handle appropriately
Also what do you mean by:
User is unverified.
In case user is not Authenticated (api doesn't know who is he), api is supposed to return 401 http status code. If user lacks some permission and therefore cannot modify the resource than 403 is totally fine. However it would be great to describe which permission exactly is missing

Related

What should be the Rest URL for the action "Move the competitor from team1 to to team2"

I am looking for a good URL, following REST principes, to "Move the competitor from team1 to to team2
My first guess is :
/teams/{oldTeamId}/{newTeamId}/competitors/{competitorId}/move
But it doesn't look much like REST.
Should I break it into 2 basics calls ?
Remove competitor from team1,
Add competitor to team2,
Should I remove some data from URL and pass it into the body ?
I don't really know what to do for this one.
Think about how you would implement this API as a web site.
You would probably have a link to a form -- it might be a form where the competitor, old team, and new team are all blank, or it might be a form where the competitor and old team are pre-populated. Your consumer updates the default information in the form as required, and submits it.
Notice the first point (raised by Roman Vottner as well) -- your consumer doesn't need to look at the URL at all. The client knows the HTML form processing rules, so it can create the correct HTTP request without knowing anything about the domain.
The second point is that, since the client is just submitting the form to wherever the HTML tells it to, you can make that anything you want.
One of the interesting properties of HTTP is cache invalidation. See RFC 7234, any non error response to an unsafe request will invalidate all cached representations of one resource.
So you can choose which resource gets invalidated by specifying its URI as the target of the form. In effect, it gives you a mechanism for ensuring that a consumer can read its own writes.
So some reasonable choices for the target might be
/teams/{oldTeamId}
if the team roster is the most important thing. Or
/competitors/{competitorId}
if the resource that describes the player is what is most important.
I don't really know what to do for this one.
Concentrate on make it easy to use. Your resource model is not your domain model is not your data model.
It will likely be useful to watch Jim Webber's talk REST: DDD In the Large to get clearer insights into what your "REST" API should really look like.
To answer your questions, I would not break it into two calls, I would however take some data from that (GET) url and put it in the body of your request. The request would probably be a POST or PUT (or maybe even patch), but definitely not a GET since something is actually changing.
As for a solution, how about a POST request to a /transfer. After all you are (could be) creating a new transfer which takes for example the player, their new team and maybe their old team.
I would use URL to identify the resource which in this case seems to be a competitor's team.
So would
Make the url as /competitors/{competitorId}/teams
Make the call PUT
Have a body with newTeamId and if required the oldTeamId.

Logging in with REST API

I am building a user account service which handles basic log in/out and view/edit account profile etc.
They enter their email and password which I need to authenticate. Please do not comment on any security issues (API not public etc) thanks!
The service has a RESTful API so was considering how best I design the API. I have some options...
GET api/accounts?email=x&password=y
Returns an array of Accounts of size 1 if valid (or 0 if not)
or
POST api/login_requests (where body contains email/passwword)
Returns an Account if valid (or Not Found if not)
I'm thinking the latter but not sure this is really restful (I don't really have login_request resources - so seems a bit procedural).
Thoughts? Maybe there are other options/standard approaches?
GET, in HTTP protocol communication term, try to 'read' information . And this itself have possible states value that can be handler, (200, 201, 400, 404) .
If the case is such static response, (like 1 or 0 if not) , would be a clever option directly resolve with the protocol (it why it exist ) .

Rest convention: Should api send details api url for listings or clients hard code them?

We have listing and details page for mobile, desktop, android and ios?
We have two apis- one for listing and other for details of those listings. So one api is assosiated with other.
listing api looks like:
/api/books/?price=100-300
details api looks like:
/api/book/{bookId}
listing api in response sends back details api link for each listing:
For example:
Request:
/api/books/?price=100-300
will have Response:
{
"books":[
{
"id": 1,
"price": 120,
"pages": 400,
"detailsUrl": "/api/book/{bookId}"
}
]
}
The problem is, should I send detailsUrl with each listing or let all the clients create this? Since they have bookId, they can create it.
What is considered to be best practise considering the url params in details api url may get added in future, api may be versioned and all other possibilities for widely used apis?
I'd put my money on creating the link.
There is a perfect explanation why putting id is not enough
DO NOT include just an entity's ID (such as 12) in a response, because
that way you're forcing clients to put together resource URIs
themselves. In order to do that, they would need to have prior
knowledge of what URIs there are, and you're losing control over the
URI space on the server side.
I recommend to read the entire, linked text (approved answer), it's very detailed and got nice resources. As the author mentioned, there is a popular convention how to make connections between resources - HAL. Consider this instead of detailsUrl.
Even if a link to the resource is obvious right now and you decided to put id alone, in other resources after some time it won't be so simple and you will be forced to specify full URL. Then your API won't be consistent. Experience has taught me it's always easier and better for maintenance to send back full link.

Always get "Error validating verification code." when requesting access_token

Well, I have done all my best to try to solve this problem, but, still, it's too annoying.
I decided to use OAuth with server-side authentication. So, I have followed Facebook documentation, and I have done the following step.
Create a link which redirect people to log in Facebook by https://www.facebook.com/dialog/oauth?client_id={APP_ID}&redirect_uri=http://abc.com/nextStep.php
In nextStep.php, redirect people to https://graph.facebook.com/oauth/access_token?code={CODE GENERATED BY FACEBOOK}&client_id={APP_ID}&redirect_uri=http://abc.com/thirdStep.php&client_secret={APP_SECRET}
The problem exists when proceeding to step 2. The page shows that:
{
"error": {
"message": "Error validating verification code.",
"type": "OAuthException",
"code": 100
}
}
I have googled for lots of time. Some people suggests to add a trailing slash in the redirect_uri, but it doesn't work. What should I do? And how can I get the user information after getting the access_token? Thanks for your help.
Two things:
First, I’d say you’re missing the state parameter in your first URL … you have to make up a value that the docs describe as SOME_ARBITRARY_BUT_UNIQUE_STRING – some unique id/hash/whatever, that no one from the outside would be able to guess. (Yes, that parameter is optional – but you should use it anyway, because as the docs say it helps prevent CSRF and is therefore an important security measure. If you don’t know what CSRF means, please look it up.)
And second, in your step two, you should not redirect the user’s client to that address, but make a server side call to that endpoint instead. You are putting your app secret into this URL (that’s not the mistake, you have to) – so it would be easy for the user to get it if you called that URL in his browser …!
I’d suggest you start with https://developers.facebook.com/docs/authentication/server-side/ again, reading it carefully from the top – you can hardly go wrong if you really follow the instructions given there one-by-one …

Twitter API : Decode string returned by getFollowerIDsFor from Twitter (MGTwitterEngine for Obj-C)

New Question
Thank you for your reply Arcain. I guess question got mis-represented. I apologize for that.
My interpretation was like getFollowerIDsFor method as name suggests should be getting list of follower IDs, but it is not so.
My actual question is, how to use MGTwitterEngine API to get list of follower/following persons from Twitter. Though I went through documentation was not able to find out the same.
Regards,
Jennis
Previous Question
We can get list of Follower using getFollowerIDsFor through MGTwitterEngine object. It always returns some string which is not understandable for me i.e. how to decode or something like that ?
let say resultant string is "025815FA-BAF6-49E6-96B4-86F2D4C8C6CA"
how to understand what is there in this string ? can anyone highlight on this please ?
Help would be appreciated.
Regards,
Jennis
That value is a unique identifier and doesn't really mean anything. I'm not familiar with Cocoa, but when I looked around I found the following in the README file for MGTwitterEngine, and it seems relevant to what you're asking:
A note about the data returned from Twitter
Each Twitter API method returns an NSString which is a unique
identifier for that connection.
Those identifiers are passed to all
the delegate methods, so you can
keep track of what's happening.
Whenever a request is successful, you will receive a call to your
implementation of requestSucceeded: so
you'll know that everything went OK.
For most of the API methods, you will
then receive a call to the appropriate
method for the type of data you
requested (statusesReceived:... or
directMessagesReceived:... or
userInfoReceived:...). The values sent
to these methods are all NSArrays
containing an NSDictionary for each
status or user or direct message, with
sub-dictionaries if necessary (for
example, the timeline methods usually
return statuses, each of which has a
sub-dictionary giving information
about the user who posted that
status).
Just try calling some of the methods and use NSLog() to see what data you
get back; you should find the format
very easy to integrate into your
applications.
Sometimes, of course, requests will fail - that's just how life is. In the
unlikely event that the initial
connection for a request can't be
made, you will simply get nil back
instead of a connection identifier,
and then receive no further calls
relating to that request. If you get
nil back instead of an NSString, the
connection has failed entirely. That's
a good time to check that the computer
is connected to the internet, and so
on.
It's far more common however that the connection itself will go ahead just
fine, but there will be an error on
Twitter's side, either due to
technical difficulties, or because
there was something wrong with your
request (e.g. you entered the wrong
username and password, or you tried to
get info on a user that doesn't exist,
or some such thing). The specific
error conditions are mostly documented
in the Twitter API documentation
online.
In these cases you'll receive a call to requestFailed:withError: which will
include an NSError object detailing
the error. Twitter usually returns
meaningful HTTP error codes (like 404
for 'user not found', etc), and in
that case the -domain of the NSError
will be "HTTP" and the -code will be
the relevant HTTP status code. The
userInfo of the NSError will contain a
key "body" that may contain the
response body and "response" which
will contain the NSHTTPURLResponse.
This makes it really, really easy to
know what's happening with your
connections.