Web services - REST vs PHP JSON RPC - php

I am working on a project where I am trying to expose the function of the software. Basically I have my backend set up and was thinking of seperating the frontend from the backend code using JSON msgs. I am a little bit confused as to what is the difference between a service and an API. I know API can be build on top on services. But I have these two models in mind -- to access profile X using json-rpc
http://xyz.com/?request={"jsonrpc":"2.0","id":1,"method":"getProfile","params":{"id":"X"}}
or should it be like this using REST -
http://api.xyz.com/X
Thank You

"Service" vs "API" is a pretty vague question. Often, the two terms are used interchangeably. "REST" vs "RPC" is a little easier to explain.
Usually with REST, a URL represents a specific resource such as a "user", an "account", etc.. Typically, you can create/retrieve/update/delete these resources by using the HTTP methods POST/GET/PUT/DELETE. To update the profile for user 1125 you might send the following:
POST /user/1125 HTTP/1.1
Host: wherever.com
Content-type: application/x-www-form-urlencoded
firstName=Davey&lastName=Jones&email=dj%40thebrineydeep.com
Anything you wanted to do with user 1125, you would send a request to the same URL. There are exceptions and variants of this idea, but that's the crux of it.
RPC services is more like just using a function library, which is bound to a specific URL. You might have a whole bunch of related functions all bound to the URL /services/json. Then if you wanted to change the profile for old Davey Jones, you would:
POST /services/json HTTP/1.1
Host: wherever.com
Content-type: application/json
{ "jsonrpc": "2.0",
"id": 1,
"method": "setProfile",
"params": [ 1125,
{ "firstName": "Davey",
"lastName": "Jones",
"email": "dj#thebrineydeep.com"
}
]
}
I personally like JSON-RPC better because:
I don't have to try and fit all of my function calls into some kind of resource-to-url mapping that might not make sense
We don't try to overload the HTTP response codes to indicate API errors. Every request returns a 200 response (unless there is a server error) and you know from the response body whether you got an error or not. JSON-RPC is particularly good at being explicit about error conditions.
Sometimes REST is better because:
Sometimes the resource-to-URL mapping fits really well
It is more intuitive for third parties to understand
It offers a simpler model for just retrieving easily-identified information
I don't think either one is any easier to code.
Edit I changed the REST example to use the more common form-encoded data instead of JSON. But of course you can specify any data format you like with REST. It isn't carved in stone.

Your REST URL does not equal your JSON-RPC request.
At least it should be http://api.example.org/getProfile?id=X
There really is not much difference between the two. And your "REST" isn't a real REST unless you return a data format that reliably can express links to different URLs, e.g. XML or (X)HTML. Until this requirement is met, you should only call it "RESTful", because you really only use HTTP methods to trigger stuff and move data back and forth.
It doesn't really matter what you use - unless you know or have experience with software that supports you building one or the other solution more rapidly than the other.

Related

how to reduce RestFull Api response size?

I have a web site witch using Angularjs to connect to An api written in php to get data and perform action and ths api send a json result. in checking site performance I found that my server response is very lass than downloading response from the web!!!
how can I change json property name by shorter aliases? for example:
{
"name": "test",
"family": "testi"
}
must be converted to:
{
"n": "test",
"f": "testi"
}
indeed in 2nd form of response content length is much shorter if my response contain an array of object.
is there any technology for client and server side for this issue? or is there any other solution?
We can compress our response by GZIP. also there is some high-performance serialization protocol like Protobuff or Thrift those are fast and secure but I think they are server to server solutions and using them in front-end area can not be a very efficient solution. also, We can create some mapping that can map our minimized property names in back-end DTOs to our front-end data models.
They are the solutions founded in my explorations and experiences. Any new suggestions are welcomed;

Need help understanding RESTful apis in PHP

For a few weeks, I've been trying to gather as much information on implementation of RESTful apis in PHP as I can but in vain. All the information that is given online only explain the most basic concepts but never did I come across a very real example with complete code on how RESTapi actually works.
For Example, POST is used create a new resource. But how? How is it implemented in real life? How do I do this in cURL? I am aware of the complete basics but am unable to find any concrete and complete example that explains everything. Most of the tutorials simply name the functions they've used but did not bother explaining what is happening exactly, what the flow of the program is, etc.
If someone can help with a complete example (say, a library registration and database) I'll really appreciate it. I'm really confused.
I will describe POST method in REST.
Client send HTTP request via POST method with JSON data.
For example, client send some data to create a word "nice".
POST http://localhost/word/1
JSON content
{
"data": {
"type": "word",
"attributes": {
"word": "nice"
}
}
}
In PHP you need get a response and convert to array and insert ot DB. Why insert? Because request method is POST.

Best Practice for Errors in RESTful API

What are the best practices for returning HTTP status codes in RESTful API? I am using Laravel 4 for my PHP framework.
In the case of an error, should I use
return Response::json('User Exists', 401);
or
include flag for success
return Response::json([
'success' => false,
'data' => 'User Exists'],
401
);
or
use 200 instead of 4xx, relying on success to determine if there is an error
return Response::json([
'success' => false,
'data' => 'User Exists'],
200
);
And in the case of success and there is no need to return any data, do you still return anything?
PHP API Code
public function getCheckUniqueEmail() {
// Check if Email already exist in table 'users'
$uniqueEmail = checkIfEmailExists();
// Return JSON Response
if($uniqueEmail) {
// Validation fail (user exists)
return Response::json('User Exists', 401);
} else {
// Validation success
// - Return anything?
}
}
When you look at the list of available HTTP status codes, you will at some point realize that there are plenty of them, but used alone they cannot really explain an error by itself.
So to answer your question, there are two parts. One is: How can your API communicate the reasons for an error and add useful information that the user of the API (which in most cases is another developer) can read and act upon. You should add as much information as possible, both machine readable and human readable.
The other part: How can HTTP status codes help in distinguish certain error (and success) states?
This latter part is actually harder than one might thing. There are the obvious cases where 404 is used to tell "not found". And 500 for any errors that are server-side.
I wouldn't use status 401, unless I really want to allow the operation to succeed if there are HTTP authentication credentials present. 401 usually triggers a dialog box in the browser, which is bad.
In case of a ressource being unique and already existing, status "409 Conflict" seems appropriate. And if creating a user succeeds, status "201 Created" sounds like a good idea, too.
Note that there are a lot more status codes, some of them related to extensions of the HTTP protocol (like DAV), some completely unstandardized (like status "420 Enhance your calm" from the Twitter API). Have a look at http://en.wikipedia.org/wiki/List_of_HTTP_status_codes to see what has been used so far, and decide whether you want to use something appropriate for your error cases.
From my experience, it is easy to simply pick a status code and use it, but it is hard to do so consistently and in accordance with existing standards.
I wouldn't however stop here just because others might complain. :) Doing RESTful interfaces right is a hard task in itself, but the more interfaces exists, the more experience has been gathered.
Edit:
Regarding versioning: It is considered bad practice to put a version tag into the URL, like so: example.com/api/v1/stuff It will work, but it isn't nice.
But the first thing is: How does your client specify which kind of representation he wants to get, i.e. how can he decide to either get JSON or XML? Answer: With the Accept header. He could send Accept: application/json for JSON and Accept: application/xml for XML. He might even accept multiple types, and it is for the server to decide then what to return.
Unless the server is designed to answer with more than one representation of the resource (JSON or XML, client-selected), there really isn't much choice for the client. But it still is a good thing to have the client send at least "application/json" as his only choice and then return a header Content-type: application/json in response. This way, both sides make themselves clear about what they do expect the other side to see the content like.
Now for the versions. If you put the version into the URL, you effectively create different resources (v1 and v2), but in reality you have only one resource (= URL) with different methods to access it. Creating a new version of an API must take place when there is a breaking change in the parameters of a request and/or the representation in the response which is incompatible with the current version.
So when you create an API that uses JSON, you do not deal with generic JSON. You deal with a concrete JSON structure that is somehow unique to your API. You can and probably should indicate this in the Content-type sent by the server. The "vendor" extension is there for this: Content-type: application/vnd.IAMVENDOR.MYAPI+json will tell the world that the basic data structure is application/json, but it is your company and your API that really tells which structure to expect. And that's exactly where the version for the API request fits in: application/vnd.IAMVENDOR.MYAPI-v1+json.
So instead of putting the version in the URL, you expect the client to send an Accept: application/vnd.IAMVENDOR.MYAPI-v1+json header, and you respond with Content-type: application/vnd.IAMVENDOR.MYAPI-v1+json as well. This really changes nothing for the first version, but let's see how things develop when version 2 comes into play.
The URL approach will create a completely unrelated set of new resources. The client will wonder if example.com/api/v2/stuff is the same resource as example.com/api/v1/stuff. The client might have created some resources with the v1 API and he stored the URLs for this stuff. How is he supposed to upgrade all these resources to v2? The resources really have not changed, they are the same, the only thing that changed is that they look different in v2.
Yes, the server might notify the client by sending a redirect to the v2 URL. But a redirect does not signal that the client also has to upgrade the client part of the API.
When using an accept header with the version, the URL of the resource is the same for all versions. The client decides to request the resource with either version 1 or 2, and the server might be so kind and still answers version 1 requests with version 1 responses, but all version 2 requests with the new and shiny version 2 responses.
If the server is unable to answer to a version 1 request, he can tell the client by sending HTTP status "406 Not Acceptable" (The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.)
The client can send the accept header with both versions included, which enabled the server to respond with the one he likes most, i.e. a smart client might implement versions 1 and 2 and now sends both as accept header, and waits for the server to upgrade from version 1 to 2. The server will tell in every response whether it is version 1 or 2, and the client can act accordingly - he does not need to know the exact date of the server version upgrade.
To sum it up: For a very basic API with limited, maybe internal, usage even having a version might be overkill. But you never know if this will be true a year from now. It is always a very good idea to include a version number into an API. And the best spot for this is inside the mime type that your API is about to use. Checking for the single existing version should be trivial, but you have the option of transparently upgrading later, without confusing existing clients.
I wouldn't use 200 status for everything. That just would be confusing.
Jquery allows you to process different response codes differently, there are built in methods for that already so take advantage of using them in your apps and when your app grows you can provide that API for others to use too.
Edit:
Also I highly recommend watching this talk about Laravel and API development:
http://kuzemchak.net/blog/entry/laracon-slides-and-video
There are some list of HTTP Status Code at Illuminate\Http\Response that extend to Symfony\Component\HttpFoundation\Response. You can use that in your class.
For example:
use Illuminate\Http\Response as LaravelResponse;
...
return Response::json('User Exists', LaravelResponse::HTTP_CONFLICT);
It much more readable.

Should Rest API accept POST array or JSON string?

I've been reading a few REST tutorials and some of them says that in order to send data to a rest API you should send post data as an array, which is something like this:
$data = array('foo' => 'bar');
$rest->post($data);
Then there are others that say you should send JSON data like this:
$data = array('foo' => 'bar');
$data = json_encode($data);
$rest->post($data);
Not sure if there's a standard way of doing this or either if is fine but what is generally recommended when designing API's?
EDIT: There seems to be confusion. To clarify I agree JSON should be used for client consumption but this question is about SERVER consumption. Meaning should the SERVER accept JSON or POST data from its clients?
If you're the one creating the RESTful API, meaning your application is the server and is accepting requests, then your question seems confusing. Your application will not be sending any POST data; clients will be sending POST data to you.
With that being said, having an API which will accept JSON-encoded requests is possible, though would really only be useful for very niche scenarios. The vast majority of clients will be POSTing data to your API in the application/x-www-form-urlencoded format. PHP handles this behind the scenes for you, and exposes the data as the $_POST superglobal.
If you're talking about responding to POST requests, and what format you should use, then that will depend on what format the client wants you to send it in. The client will either specify this in the Accept header, or some APIs allow it to be specified in the URL (e.g. foo.com/some/thing/123.json or foo.com/some/thing/123/json). The client isn't required to tell your application what format it wants, so it's up to you to pick a sensible default. Most APIs will use JSON these days.
I've never heard of an API that understood serialized PHP array format, though, so I don't know what resources you've been reading, but I'm pretty sure you misunderstood what they were suggesting.
Actually, I think this is a pretty good question. don't know why it got downvoted.
Also, contrary to what I saw written in some comments, the client can use any language he wants, not only javascript. And it's not the server job to know which language was used to "build" the request, just that the request is valid. This makes more sense if you think that the entity making the request can actually be another server (think about a proxy server used to send post requests across domains).
That being said, personally, I think it's better for the server side to consume a XML or JSON. The main reason is validation.
It's easier to validate a XML or JSON against a schema.
Also the schema can be made public, and a well designed schema can describe webservice by itself. The client can even use the same schema to validate the request prior to sending it to the server.
Passing an url encoded form is also valid, of course. And can be validated server side as well. SO i think, down the road, it's just a matter of preference.
Also, check this discussion in SO, it regards the same topic:
JSON vs Form POST
You should think about the clients that will consume the API. A HTML5\AJAX client will probably want JSON data, while other clients (Silverlight or native mobile apps) might be better at consuming XML.
One great framework\platform for writing REST API's is looking to be Microsoft's Web API (based on ASP.NET MVC). The product succeeds the WCF framework and allows users to write REST API's in a MVC environment. One feature is that it chooses a serialization provider based on the HTTP Accept header.
So if a client Accepts application/json they work with the service in JSON and if the accept XML they work with the service in XML. You can also write your own object serializer and plug it into the framework.
More information: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/video-your-first-web-api
Most of the time you would want to stick to receiving POST data but I think receiving json data does have its uses for example when it comes to batch requests.
The Facebook API uses it.
You don't need to do file_get_contents('php//input'). From the facebook documentation you could just do something like this:
curl -X POST "http://example.com/batch" -d 'batch={ "param" : 1, "param2" : "2"}'
Then in the PHP code, if you're using PHP, you can get it through the $_POST parameter and do a json_decode.
var_dump($_POST);
array(1) {
["batch"]=>
string(30) "{ "param" : 1, "param2" : "2"}"
}
var_dump(json_decode($_POST['batch'], true));
array(2) {
["param"]=>
int(1)
["param2"]=>
string(1) "2"
}
JSON makes more sense, since it is language-independent and can be useful when API scales.
I am currently developing a REST API and I was asking myself the same question. After some research I found out that is no standard and is totally up to you.
You are developing the server side so you can decide how data should be sent to you. The client need to adapt to your design.
Personally I choose to receive all POST and PUT data as JSON directly in body.
The point is to reuse the HTTP implementation that already exists.
HTTP is built to accept many different content-types and you only need to specify which you are using in the headers.
A REST API that accepts the various formats and works off the content-type header is refreshing. You can submit x-www-form-urlencoded values from an HTML webpage or make an AJAX request with raw JSON and there is no confusion as long as everyone is following protocol.
As a developer you must choose the support your app will provide because you can't support everything. Typically it boils down to the support or convenience of your own environment -- nobody wants to reinvent the wheel.
Many frameworks that are designed with building APIs in mind, handle the most popular content types at a lower level. They may also encode the response data according to the "Accept" header.
Implement whatever you think will be used most first or find a framework that already speaks HTTP and takes care of all of that for you.

REST API - why use PUT DELETE POST GET?

So, I was looking through some articles on creating REST API's.
And some of them suggest using all types of HTTP requests: like PUT DELETE POST GET.
We would create for example index.php and write API this way:
$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(#$_SERVER['PATH_INFO'], 1));
switch ($method) {
case 'PUT':
....some put action....
break;
case 'POST':
....some post action....
break;
case 'GET':
....some get action....
break;
case 'DELETE':
....some delete action....
break;
}
OK, granted - I don't know much about web services (yet).
But, wouldn't it be easier to just accept JSON object through regular POST or GET (that would contain method name and all parameters) and then respond in JSON as well. We can easily serialize/deserialize via PHP's json_encode() and json_decode() and do whatever we want with that data without having to deal with different HTTP request methods.
Am I missing something?
UPDATE 1:
Ok - after digging through various API's and learning a lot about XML-RPC, JSON-RPC, SOAP, REST I came to a conclusion that this type of API is sound. Actually stack exchange is pretty much using this approach on their sites and I do think that these people know what they are doing Stack Exchange API.
The idea of REpresentational State Transfer is not about accessing data in the simplest way possible.
You suggested using post requests to access JSON, which is a perfectly valid way to access/manipulate data.
REST is a methodology for meaningful access of data. When you see a request in REST, it should immediately be apparant what is happening with the data.
For example:
GET: /cars/make/chevrolet
is likely going to return a list of chevy cars. A good REST api might even incorporate some output options in the querystring like ?output=json or ?output=html which would allow the accessor to decide what format the information should be encoded in.
After a bit of thinking about how to reasonably incorporate data typing into a REST API, I've concluded that the best way to specify the type of data explicitly would be via the already existing file extension such as .js, .json, .html, or .xml. A missing file extension would default to whatever format is default (such as JSON); a file extension that's not supported could return a 501 Not Implemented status code.
Another example:
POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }
is likely going to create a new chevy malibu in the db with the associated colors. I say likely as the REST api does not need to be directly related to the database structure. It is just a masking interface so that the true data is protected (think of it like accessors and mutators for a database structure).
Now we need to move onto the issue of idempotence. Usually REST implements CRUD over HTTP. HTTP uses GET, PUT, POST and DELETE for the requests.
A very simplistic implementation of REST could use the following CRUD mapping:
Create -> Post
Read -> Get
Update -> Put
Delete -> Delete
There is an issue with this implementation: Post is defined as a non-idempotent method. This means that subsequent calls of the same Post method will result in different server states. Get, Put, and Delete, are idempotent; which means that calling them multiple times should result in an identical server state.
This means that a request such as:
Delete: /cars/oldest
could actually be implemented as:
Post: /cars/oldest?action=delete
Whereas
Delete: /cars/id/123456
will result in the same server state if you call it once, or if you call it 1000 times.
A better way of handling the removal of the oldest item would be to request:
Get: /cars/oldest
and use the ID from the resulting data to make a delete request:
Delete: /cars/id/[oldest id]
An issue with this method would be if another /cars item was added between when /oldest was requested and when the delete was issued.
This is a security and maintainability question.
safe methods
Whenever possible, you should use 'safe' (unidirectional) methods such as GET and HEAD in order to limit potential vulnerability.
idempotent methods
Whenever possible, you should use 'idempotent' methods such as GET, HEAD, PUT and DELETE, which can't have side effects and are therefore less error prone/easier to control.
Source
In short, REST emphasizes nouns over verbs. As your API becomes more complex, you add more things, rather than more commands.
You asked:
wouldn't it be easier to just accept JSON object through normal $_POST and then respond in JSON as well
From the Wikipedia on REST:
RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it
From what (little) I've seen, I believe this is usually accomplished by maximizing the use of existing HTTP verbs, and designing a URL scheme for your service that is as powerful and self-evident as possible.
Custom data protocols (even if they are built on top of standard ones, such as SOAP or JSON) are discouraged, and should be minimized to best conform to the REST ideology.
SOAP RPC over HTTP, on the other hand, encourages each application designer to define a new and arbitrary vocabulary of nouns and verbs (for example getUsers(), savePurchaseOrder(...)), usually overlaid onto the HTTP 'POST' verb. This disregards many of HTTP's existing capabilities such as authentication, caching and content type negotiation, and may leave the application designer re-inventing many of these features within the new vocabulary.
The actual objects you are working with can be in any format. The idea is to reuse as much of HTTP as possible to expose your operations the user wants to perform on those resource (queries, state management/mutation, deletion).
You asked:
Am I missing something?
There is a lot more to know about REST and the URI syntax/HTTP verbs themselves. For example, some of the verbs are idempotent, others aren't. I didn't see anything about this in your question, so I didn't bother trying to dive into it. The other answers and Wikipedia both have a lot of good information.
Also, there is a lot to learn about the various network technologies built on top of HTTP that you can take advantage of if you're using a truly restful API. I'd start with authentication.
In regards to using extension to define data type.
I noticed that MailChimp API is doing it, but I don't think this is a good idea.
GET /zzz/cars.json/1
GET /zzz/cars.xml/1
My sound like a good idea, but I think "older" approach is better - using HTTP headers
GET /xxx/cars/1
Accept: application/json
Also HTTP headers are much better for cross data type communication (if ever someone would need it)
POST /zzz/cars
Content-Type: application/xml <--- indicates we sent XML to server
Accept: application/json <--- indicates we want get data back in JSON format
Am I missing something?
Yes. ;-)
This phenomenon exists because of the uniform interface constraint. REST likes using already existing standards instead of reinventing the wheel. The HTTP standard has already proven to be highly scalable (the web is working for a while). Why should we fix something which is not broken?!
note: The uniform interface constraint is important if you want to decouple the clients from the service. It is similar to defining interfaces for classes in order to decouple them from each other. Ofc. in here the uniform interface consists of standards like HTTP, MIME types, URI, RDF, linked data vocabs, hydra vocab, etc...
Good Semantics is important in programming.
Utilizing more methods besides GET/POST will be helpful because it will increase the readability of your code and make it easier to maintain.
Why?
Because you know GET will retrieve data from your api. You know POST will add new data to your system. You know PUT will make updates. DELETE will delete rows etc, etc,
I normally structure my RESTFUL Web Services so that I have a function callback named the same thing as the method.
I use PHP, so I use function_exists (I think its called). If the function doesn't exist, I throw a 405 (METHOD NOT ALLOWED).
Bill Venners: In your blog post entitled "Why REST Failed," you said that we need all four HTTP verbs—GET, POST, PUT, and DELETE— and lamented that browser vendors only GET and POST." Why do we need all four verbs? Why aren't GET and POST enough?
Elliotte Rusty Harold: There are four basic methods in HTTP: GET, POST, PUT, and DELETE. GET is used most of the time. It is used for anything that's safe, that doesn't cause any side effects. GET is able to be bookmarked, cached, linked to, passed through a proxy server. It is a very powerful operation, a very useful operation.
POST by contrast is perhaps the most powerful operation. It can do anything. There are no limits as to what can happen, and as a result, you have to be very careful with it. You don't bookmark it. You don't cache it. You don't pre-fetch it. You don't do anything with a POST without asking the user. Do you want to do this? If the user presses the button, you can POST some content. But you're not going to look at all the buttons on a page, and start randomly pressing them. By contrast browsers might look at all the links on the page and pre-fetch them, or pre-fetch the ones they think are most likely to be followed next. And in fact some browsers and Firefox extensions and various other tools have tried to do that at one point or another.
PUT and DELETE are in the middle between GET and POST. The difference between PUT or DELETE and POST is that PUT and DELETE are *idempotent, whereas POST is not. PUT and DELETE can be repeated if necessary. Let's say you're trying to upload a new page to a site. Say you want to create a new page at http://www.example.com/foo.html, so you type your content and you PUT it at that URL. The server creates that page at that URL that you supply. Now, let's suppose for some reason your network connection goes down. You aren't sure, did the request get through or not? Maybe the network is slow. Maybe there was a proxy server problem. So it's perfectly OK to try it again, or again—as many times as you like. Because PUTTING the same document to the same URL ten times won't be any different than putting it once. The same is true for DELETE. You can DELETE something ten times, and that's the same as deleting it once.
By contrast, POST, may cause something different to happen each time. Imagine you are checking out of an online store by pressing the buy button. If you send that POST request again, you could end up buying everything in your cart a second time. If you send it again, you've bought it a third time. That's why browsers have to be very careful about repeating POST operations without explicit user consent, because POST may cause two things to happen if you do it twice, three things if you do it three times. With PUT and DELETE, there's a big difference between zero requests and one, but there's no difference between one request and ten.
Please visit the url for more details. http://www.artima.com/lejava/articles/why_put_and_delete.html
Update:
Idempotent methods
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself. This still can be manipulated (like an update-timestamp, provided this information is not shared in the (current) resource representation.
Consider the following examples:
a = 4;
a++;
The first example is idempotent: no matter how many times we execute this statement, a will always be 4. The second example is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times. Since both examples are changing the value of a, both are non-safe methods.
Basically REST is (wiki):
Client–server architecture
Statelessness
Cacheability
Layered system
Code on demand (optional)
Uniform interface
REST is not protocol, it is principles.
Different uris and methods - somebody so called best practices.

Categories