How to enable dojox.data.JsonRestStore access struts2's action to retrieve data? I mean how to configure 'target' or others - dojo

I tend to use dojox.data.JsonRestStore as my grid's store, but I am always failed to access struts2 action, I am unfamiliar in REST, is it only can be used in servlet rather than struts2, etc.
Currently, My project is using struts2 + spring as backend skill and dojo as front-side skill, have you any ways for me to make dojox.data.JsonRestStore access a structs2 action class?
Thanks in advance.

to get the data, all you need is an HTTP GET that returns an array of JSON objects. The return value from the action must be a string with something like:
[
{
"penUser":"Micha Roon",
"submitTime":"12.03 13:20",
"state":"Eingang",
"FormNumber":"001001"
},
{
"penUser":"Micha Roon",
"submitTime":"12.03 13:20",
"state":"Eingang",
"FormNumber":"001001"
}
]
If you want to be able to update objects you have to have a method that reacts to PUT with the same URL as the one you used for GET and if you need to delete, DELETE will be used. The important part is that it must be the same URL.
In order to have JsonRestStore pass the ID in a GET parameter instead of appending it to the URL, you could specify the URL like so:
target:"services/jsonrest/formstore?formId="
When you call yourStore.get("123") the request will try to get http://yourserver:port/AppContext/services/jsonrest/formstore?formId=123
REST is nothing more than a convention.
You can use a RESTFull API like jersey.java.net in order to make your life easier and your URL more RESTFull.

Related

How do I just add a custome variable to a Survey Monkey?

I am handling existing surveys via the API.
As part of this, I need each survey to have a custom variable defined for it.
I would like to use the API to add the custom variable, but the documentation states the FETCH would not do that, and PUT will replace rather than update the survey.
I am handling existing surveys, which I would not like to delete and replace, or am I miss-reading the docs?
Can I just send via PUT the following structure and it will keep everything else in place?
{
id : 112223333, //id of survey
custom_variables: {
'custom1':'custom1',
'custom2':'custom2'
}
}
I do see it resets the title, so, is this method safe? (i.e. wont remove any other data associated to this survey).
You're on the right track. You're going to want to use a PATCH HTTP request. That will only make updates, whereas a PUT request will replace the survey with the content you provide.
So your request will likely look something like this:
PATCH /v3/surveys/<survey_id>
{
"custom_variables": {
"custom1_name": "custom1_label",
"custom2_name": "custom2_label"
}
}
And that should only update your custom variables to the values you set. The docs do appear to suggest custom_variables won't get updated with a PATCH request but I think it does work.

Sails.js: How to access and modify req.params in middleware

I want to implement a mechanism to obfuscate the id fields in my application . Right now all the id fields are integers. I want to use some sort of reversible hashing to create random strings corresponding to the id fields. Also, I am trying to accomplish this with minimal changes to the overall project.
One thing that came to my mind was to write a middleware to intercept every request and response object and check for the presence of id field. If the request contains id field and it is an obfuscated version, decode the string and replace the request parameter with the integer id.
If the response contains the integer id, run the encode function on it to send the obfuscated id to the client.
The problem I am facing is with modifying the req object. The id field can be present in req.body or req.params or res.query. However, in the middleware, I cannot see the id field when it is present in req.params.
I tried using policies. But the problem I am facing there is even after changing the req.params, the changes are lost when the control reaches the controller. What would be the recommended way of solving this problem ?
Here is the sample code:
In the policy:
module.exports = function (req, res, next) {
req.params.id = '12345';
req.query.pageSize = 30;
req.body = {};
sails.log.info('req.params', req.params);
sails.log.info('req.query', req.query);
sails.log.info('req.body', req.body);
return next();
};
I am just modifying values of req.params, req.query and req.body.
When I try to access these values in the controller, the values of req.query and req.body are the modified values as changed in the policy. However, req.params changes back to what was sent by the client and the changes made in the policy are lost
I think you are confusing policy and middleware? Is your code above in api/policies? If so, you still need to define which controller(s) this policy is applied to in config/policies.
So config/policies.js should look like:
modue.exports.policies = {
// If you really want this policy for every controller and action
'*': 'policyName.js',
// If you want it for a specific controller. '*' denotes every action in controller
specificController: {
'*': 'policyName.js'
},
// If you want it for a specific action on a specific controller
specificController: {
'specificAction': 'policyName.js'
}
};
Also I'd like to add. Policies are generally meant for authorization of controllers but this seems like a decent use case. Since every single request is not going to have these fields this should be a policy. Policies are great when applying something to a handful of controllers/actions. Middleware is great when you need to apply to every single action that comes into your app.
http://sailsjs.org/documentation/concepts/policies
http://sailsjs.org/documentation/concepts/middleware
Gitter response:
sgress454 #sgress454 10:45
#mandeepm91
In the policy, if I change req.body or req.query, the changes persist in the next policy or controller. However, changes made to req.params are lost.
This is one of the main use cases for req.options. This object is intended to be used to store request data that can be mutated by one handler before being passed on to the next. The req.params object is meant to provide each handler with a copy of the original request parameters.
How you approach this really depends on what your goal is. If you really need each request handler (that is, policies and controller actions) to see an encoded version of the ID, then a good approach would be to encode the ID in a policy as #S-Stephen suggested, store that value in req.options.id and refer to that in your other request handlers. If, on the other hand, you're really only concerned with the response having the encoded ID, the suggested practice is to use the res.ok() response in your handlers (rather than res.send() or res.json), and adjust the code for that response in api/responses/ok.js to encode the ID before sending. You can also use a custom response if this is only required for certain requests. See custom responses for more info.
Hi #sadlerw, you should be able to modify the code for res.ok() in your api/responses/ok.js file to have it always return JSON if that's what you want for every response. If it's something you only want for certain actions, you could create a custom response instead and use that where appropriate.

Passing complex types to a GET operation

I use System.Net.Http.HttpClient to comunicate with my Web Api. But now I have the problem to pass a complex type with a GET method.
With POST I can do it like
Dim Client As New System.Net.Http.HttpClient()
Client.PostAsJsonAsync(Me.BaseUrl & "/api/my", new With { .Id = 5, ... })
Is there a similar possibility to do it with GET?
I'd question whether GET is the right verb here considering you need to pass a complex type, it sounds like it would be better served as a POST.
However, if you have to use a GET then you can either
Embed the parameters in the URL e.g. /api/my?field1=1&field2=2&field3=3...
Embed the data in a cookie / custom header

laravel 4 pattern filter using a wildcard

I started using Laravel 3 last week, and then found the new 4 release and I'm trying to convert now.
I have a dozen+ routes that I want to deliver to a specific controller method. i.e., "/api/v1/owners/3/dogs/1 or /api/v1/owners/3" to run "myresourcecontroller#processRequest"
In Laravel 3 I was able to use this: (note * wildcard)
Route::any('api/v1/owners*', 'owners#processRequest'); // Process tags resource endpoints
I found this example from the documentation but it gives me an error. I get a NotFoundHttpException.
//[Pattern Based Filters](http://laravel.com/docs/routing#route-filters)
Route::filter('admin', function()
{
//
});
Route::when('admin/*', 'admin');
Not sure what I'm doing wrong? Is there another way to do this?
I don't want to use the Laravel 4 restful controllers, cause they don't seem to conform to complete restful design. i.e., no verbs in the url.
I have all of my processing written, I just need to be able to route to it.
I need to be able to create new records by POST /api/v1/owners or /api/v1/owners/3/dogs
I cannot use /api/v1/owners/create.
I'm trying to avoid having to write a route for every endpoint, i.e.,
Route::any('api/v1/owners/{owner_id}', 'owners#processRequest');
Route::any('api/v1/owners/{owner_id}/dogs/{dog_id}', 'owners#processRequest');
Thank you for any help
You should make use of resourceful controllers as they're a great asset when building an API. The endpoints you described can be achieved using resource controllers and nested resource controllers.
Route::resource('owners', 'OwnersController');
Route::resource('owners.dogs', 'OwnersDogsController');
Would allow you to create an owner with POST localhost/owners and create a dog on an owner with POST localhost/owners/3/dogs.
You can then wrap these routes in a route group to get the api/v1 prefix.
Route::group(['prefix' => 'api/v1'], function()
{
Route::resource('owners', 'OwnersController');
Route::resource('owners.dogs', 'OwnersDogsController');
});
Haven't used Laravel myself, but try any('api/v1/owners/*', (note slash before asterisk) as in the example.

How can I access query string parameters for requests I've manually dispatched in Laravel 4?

I'm writing a simple API, and building a simple web application on top of this API.
Because I want to "consume my own API" directly, I first Googled and found this answer on StackOverflow which answers my initial question perfectly: Consuming my own Laravel API
Now, this works great, I'm able to access my API by doing something like:
$request = Request::create('/api/cars/'.$id, 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());
This is great! But, my API also allows you to add an optional fields parameter to the GET query string to specify specific attributes that should be returned, such as this:
http://cars.com/api/cars/1?fields=id,color
Now the way I actually handle this in the API is something along the lines of this:
public function show(Car $car)
{
if(Input::has('fields'))
{
//Here I do some logic and basically return only fields requested
....
...
}
I would assume that I could do something similar as I did with the query string parameter-less approach before, something like this:
$request = Request::create('/api/cars/' . $id . '?fields=id,color', 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());
BUT, it doesn't seem so. Long story short, after stepping through the code it seems that the Request object is correctly created (and it correctly pulls out the fields parameter and assigns id,color to it), and the Route seems to be dispatched OK, but within my API controller itself I do not know how to access the field parameter. Using Input::get('fields') (which is what I use for "normal" requests) returns nothing, and I'm fairly certain that's because the static Input is referencing or scoping to the initial request the came in, NOT the new request I dispatched "manually" from within the app itself.
So, my question is really how should I be doing this? Am I doing something wrong? Ideally I'd like to avoid doing anything ugly or special in my API controller, I'd like to be able to use Input::get for the internally dispatched requests and not have to make a second check , etc.
You are correct in that using Input is actually referencing the current request and not your newly created request. Your input will be available on the request instance itself that you instantiate with Request::create().
If you were using (as you should be) Illuminate\Http\Request to instantiate your request then you can use $request->input('key') or $request->query('key') to get parameters from the query string.
Now, the problem here is that you might not have your Illuminate\Http\Request instance available to you in the route. A solution here (so that you can continue using the Input facade) is to physically replace the input on the current request, then switch it back.
// Store the original input of the request and then replace the input with your request instances input.
$originalInput = Request::input();
Request::replace($request->input());
// Dispatch your request instance with the router.
$response = Route::dispatch($request);
// Replace the input again with the original request input.
Request::replace($originalInput);
This should work (in theory) and you should still be able to use your original request input before and after your internal API request is made.
I was also just facing this issue and thanks to Jason's great answers I was able to make it work.
Just wanted to add that I found out that the Route also needs to be replaced. Otherwise Route::currentRouteName() will return the dispatched route later in the script.
More details to this can be found on my blog post.
I also did some tests for the stacking issue and called internal API methods repeatedly from within each other with this approach. It worked out just fine! All requests and routes have been set correctly.
If you want to invoke an internal API and pass parameters via an array (instead of query string), you can do like this:
$request = Request::create("/api/cars", "GET", array(
"id" => $id,
"fields" => array("id","color")
));
$originalInput = Request::input();//backup original input
Request::replace($request->input());
$car = json_decode(Route::dispatch($request)->getContent());//invoke API
Request::replace($originalInput);//restore orginal input
Ref: Laravel : calling your own API