Zend Based REST URI for POST and PUT methods - zend-framework

This post if a follow-up question to mt previous post:
Android RESTful Web application using Zend Framework
I have written a web application which is based on the Zend Framework (Version 1.11.11) and I want to use the SAME backend code for coding the mobile version of this application (Android). To achieve this, I want to get the response for each of the actions in the controllers in XML and JSON - for mobile-based app.
Using the answers provided in the above link, I am able to get the XML and JSON response by making use of the AjaxContext helper. I set the contexts as json for the required actions in the init method and I am getting the desired json response.
Now I have another challenge. How to know from the URL if the given action was a GET or a POST request? Do I have have to add that as a query parameter? Is that the correct way?
For example, for login action within User controller: URL will be: [link] (http://localhost/user/login)
But within the loginAction, I check if the given request if a post and authenticate only if the request is a post. So the URL: http://localhost/user/login?format=xml will always return to me the response for a GET request since there is no way of knowing if the request was a GET or POST. Please help.
Thanks.
Abhilash

like you added format parameter do the same for request . Use "method" parameter to decide what type of request is it . Or you can also do is
$this->getRequest()->isPost(); //create
$this->getRequest()->isGet(); //read
$this->getRequest()->isPut(); // update
$this->getRequest()->isDelete(); // delete

Related

How to send form data with Get method in axios?

I want to call an api with GET method and pass some form data. But seem axios is not supporting the form data with GET. Is there any way for me to overcome this problem?
ps: I am using react query and axios
You can't send a form data through GET request but you can customize the request's URL query parameters. Look at the code sample below.
//assuming instance is your axios instance.
instance.get("/test",{params:{key:value, key1:value1}}).then((data)=>{}).catch((error)=>{})
//this will send a GET request to /test?key=value&key1=value1
GET request doesn't support form data but you can use URL query parameters. Just like I did above.
For more information about axios visit axios npm package

Rest API GET method restriction

I wanted to clarify on a usecase where i struggled to use GET method for a fetch operation.
I was asked to build a API to generate message from a predefined template. In the request i receive template-ID and the dynamic content which needs to be substituted. Dynamic content vary based on the template-ID.
I have designed like
Method = POST
URL pattern = /messagegenerator/v1/templateID
Body = Dynamic Content in the form of JSON
Response = Plain text message
Problem i faced: When i use GET method then template content should be passed in the URL which has length restriction. We wanted to prepare email message which has more dynamic content.
Ultimately this service won't create any resource but still i forced to use POST method.
Am i missing something?
Rest standard missing?
Is there any better way of doing this?
Is there any restrictions on the length of get URL parameters?
Although there is no url limit in the standard, there is this old advice about keeping your urls under 2000 characters: What is the maximum length of a URL in different browsers?
To the point: in your case sending a POST request with all data in the body is the best solution. Putting email body fragments, or anything that huge (if I understand correctly) into a url is very ugly :). Even if the request does not change anything on the server technically, you should use POST, yes.
You need to create a new API which supports http get method, because one API can't receive more than on http method.
As you pointed out, in REST the POST method is thought of creating a new resource. In your case a new resource "message" is generated indeed by posting the content even if you do not keep it on the server.
But you are using POST on a template! This should create a new template. To resolve this, add a subresource to the template resource so you can express that it is a message that is created.
I would even extend the URL by adding a "template" after the "v1" to make more explicit that it is the "template" resouce on the first level.
The only change necessary for that would be to modify the URL like this:
URL pattern = /messagegenerator/v1/template/<templateID>/message
So you could have (even if you do not implement it now):
GET on /messagegenerator/v1/template/ -> Deliver a list of templates
POST on /messagegenerator/v1/template/ -> Create a new template
DELETE on /messagegenerator/v1/template/<templateID> -> Remove a template
PUT on /messagegenerator/v1/template/<templateID> -> Modify a template
GET on /messagegenerator/v1/template/<templateID>/message -> Deliver a list of messages
POST on /messagegenerator/v1/template/<templateID>/message -> Create a new message
DELETE on /messagegenerator/v1/template/<templateID>/message/<messageID> -> Remove a message
PUT on /messagegenerator/v1/template/<templateID>/message/<messageID> -> Modify a message
So you could even manage and return old messages if you saved and assigned them an ID!

Backbone Request Payload

Hi,
I am a newbie to Backbone, My Rest Server Components Accept Only XML Requests, can Anybody show an example how do i send a xml to a rest api put request.
Backbone uses JSON by default, so to use XML you need to overwrite Backbone.sync. Take a look at this answer: How to override Backbone.sync?

RestKit: POST request using named route

I am trying to use RestKit for an iOS application. So far, it works great. I have set up my routes with the router and can send requests using them.
I have been searching this for hours and can't find how to send a post request for a named route. I tried to use getObjectsAtPathForRouteNamed:object:parameters:success:failure, but it can only be used for GET requests. I know that I can send a POST request by creating a route mapped to a class using postObject:path:parameters:success:failure:, but I already have another route with POST for this class.
So the question is: Is there a way to send POST request using RestKit using named routes?
RestKit does assume that you only have one destination (route) for posting any one type of class. This is on a per-object-manager basis. So, if you want multiple different routes for a class they each need to be managed by a different instance of RKObjectManager.

Accessing JSON Resource on a RESTful one page app

Given a one page app that uses push state and RESTful backend, we can imagine accessing the listing of a resource at /resourceName (i.e. /users). So /users would create a formated list of users
Now the problem is that this resource JSON or XML feed should also be mapped to /resourceName, so if boot form my application entry point at / then all is good, when navigating to /users the JS router can trigger a Ajax call that get the JSON data. Now the problem is if the URL is pointing directly at /users then i will land on a JSON feed instead of the actual listing. I could route all call to a main entry point and then let the JS router do the work though if i do so the AJAX call to fetch JSON wil brake.
I remember a while ago people adding .json to their json request, or even a GET parameter ?format=json and then having the controller taking different actions. I find that somewhat hacky.. Are there any other ways to go about this?
For that matter i am using laravel4 backend and backboneJS
I think the .json on the end of the request is the best approach. the other approach could be to create a separate endpoint endpoint for api request api.mydomain.com vs www.mydomain.com
What method you use to get a different response depends on how you'd like to go about it. Since you're asking about an opinionated topic (There is no one right answer), here's some options you can explore.
First, here's a good read from Apigee on API design, which covers what I'll write about here. See page 20 on "Support multiple formats"
The Rails way: Append a .json, .xml or other extension at the end of your request and handle that code within Laravel (You may want to use the "before" filter to check the request or Laravel's excellent route parameters, which allow the use of regex to define the route).
You can check the "accept" header in the request and set that header in your ajax calls to "application/json" instead of the default "application/html" to inform your application which format to use in its response. Again, the before or after filters may come in handy to check the request and define the response as appropriate
Create a query string `?format=json" or similar. Same comments as in point 1.
Laravel doesn't have built-in methods to change the response for you. You can, however, fairly easily detect what's being asked and choose which format to return in. It does take some thinking about how you want to accomplish that, however.
Some options off the top of my head:
Use the "before" or "after" filter to check what the request "wants" for a format, and do some transformations on the response to make that work
Extend the request and response class to "automate" this (request class to detect format, response class to transform the response to the correct format)
Hope that helps
It's valid to say which representation do you want. E.g. JSON, XML or binary, depends on what you want and which serializers have you developed.
You framework should support either setting of default representation or if you provide some mapping URL -> method you should be able to say which representation you are going to return - also either by default or taken within some object which represents your request.
I ended up using different endpoints as suggested by #Aaron Saunders. In laravel 4 this is dumb easy to implement using group routes:
app.php:
'domain' => 'whatever.dev',
routes.php:
define('APP_DOMAIN', 'app.' . Config::get('app.domain'));
define('API_DOMAIN', 'api.' . Config::get('app.domain'));
Route::group(array('domain' => API_DOMAIN), function()
{
// API ROUTES
});
Route::group(array('domain' => APP_DOMAIN), function()
{
// VIEW ROUTES
});
Beautiful!