I am new to sails.js and I have a simple blueprint model set up. Right now, my controller and model are pretty much empty except for attribute definitions on the model.
After the model is created via POST, I would like the response to be a custom XML response (some plain text I generate essentially), not the standard JSON response. I figured that I could overwrite the entire create method on the controller, essentially copy-and-pasting the code from the default and just overwriting the response, but that seems really heavy too me.
There must be a better way to do this?
Note that I am only attempting to do this for this specific model, not generally.
Thanks!
The best way is to simply add the header as DigitalDesignDj mentioned.
/**
* TestController
*/
module.exports = {
create: function(res, req) {
// get your data
var xml = 'some xml string';
res.setHeader( "Content-type", "text/xml" );
res.send(xml);
}
}
To change headers for a specific response.
response.setHeader( "Content-type", "text/xml" );
When you already have some XML for the response.send()
If your result was to do this for all actions on that single model you could simply overwrite the toJSON method to generate XML instead of JSON in the model itself. Then if your running blueprints, it will spit out XML instead of json when you hit those endpoints.
However your question is specific to the create action. In this instance, I would ask if your running alternate view files for non ajax requests. And if not, just drop an view files into the create action that views/foo/create.[ejs,jade,ect...] with your xml layout. The response will see the view file and override the json output with that file. This means you have to change no code just add that single file.
Their are a dozen ways to accomplish this, and your question would need more detail (as mentioned on the comments) for a specific answer to your use case.
Related
I'm making a project in pyramid framework, so i have a view which have a form in it with 2 input type texts and a submit button.
The form is a post method, so im getting them with a POST request.
I want to send them to a new view and display them on the screen.
meaning:
on 0.0.0.0:6543 is the form on first view.
I want to display the values the user insert in the input on 0.0.0.0:6543/here
I tried with HTTPfound but i guess im missing an understanding on how to really pass the variables.
Please help me...
The easiest way to accomplish is to use sessions.
You need a session backend which stores your data on a server (see pyramid_redis_session). There are also cookie-based session solutions where all data is stored on the client side.
The first view writes all passed over data to a session:
request.session["mydata"] = value
The second view reads data from the session
print(request.session["mydata"])
Another way to pass the data from one view to another is via the URL. This does not require server-side support, unlike sessions. Also, it's RESTful ;)
return HTTPFound('/here?greeting=Hello&subject=World')
In your second view you then simply get the variables from request.GET:
greeting = request.GET.get('greeting', '')
subject = request.GET.get('subject', '')
# pass the data to the template
return {
"greeting": greeting,
"subject": subject
}
Regarding your comment: You can't use HTTPFound with POST. You can, however, directly submit your form to /here using <form method="post" action="/here" ...>. In this case you'll be able to access the data using request.POST.get('greeting').
I need to extend res.json so that the response goes out as text with a csrf token eg
&&&CSRF&&&{foo:bar}
Sails seems to use a different csrf methodology, but I need to do it this way to match the preexisting client side codebase.
Ideally I need to be able to create a new function:
return res.jsonWithCsrf({
foo: bar
});
Internally this would call res.json but would wrap the csfr token around the response.
I gather that I need to write a hook but am unsure how to do it.
You can create custom responses by placing your file in the api/responses directory.
You can see the files that are already there, modify them if you want, or create your own.
If you were to create jsonWithCsrf.js in that folder, then you can access it in the manner you describe above.
res.jsonWithCsrf()
http://sailsjs.org/#!/documentation/concepts/Custom-Responses
I have a few questions that I couldn't find answers anywhere online.
Does sails.js framework support HTTP PATCH method? If not - does anyone know if there is a planned feature in the future?
By default if I create method in a controller it is accessible with GET request is it the routes.js file where I need to specify that method is accessible only via POST or other type of methods?
How would you create a policy that would allow to change protected fields on entity only for specific rights having users. I.e: user that created entity can change "name", "description" fields but would not be able to change "comments" array unless user is ADMIN?
How would you add a custom header to "find" method which specifies how many items there are in database? I.e.: I have /api/posts/ and I do query for finding specific items {skip: 20; limit: 20} I would like to get response with those items and total count of items that would match query without SKIP and LIMIT modifiers. One thing that comes to my mind is that a policy that adds that that custom header would be a good choice but maybe there is a better one.
Is there any way to write a middle-ware that would be executed just before sending response to the client. I.e.: I just want to filter output JSON not to containt some values or add my own without touching the controller method.
Thank you in advance
I can help with 2 and 5. In my own experience, here is what I have done:
2) I usually just check req.method in the controller. If it's not a method I want to support, I respond with a 404 page. For example:
module.exports = {
myAction: function(req, res){
if (req.method != 'POST')
return res.notFound();
// Desired controller action logic here
}
}
5) I create services in api/services when I want to do this. You define functions in a service that accept callbacks as arguments so that you can then send your response from the controller after the service function finishes executing. You can access any service by the name of the file. For example, if I had MyService.js in api/services, and I needed it to work with the request body, I would add a function to it like this:
exports.myServiceFunction = function(requestBody, callback){
// Work with the request body and data access here to create
// data to give back to the controller
callback(data);
};
Then, I can use this service from the controller like so:
module.exports = {
myAction: function(req, res){
MyService.myServiceFunction(req.body, function(data){
res.json(data);
});
}
}
In your case, the data that the service sends back to the controller through the callback would be the filtered JSON.
I'm sorry I can't answer your other questions, but I hope this helps a bit. I'm still new to Sails.js and am constantly learning new things, so others might have better suggestions. Still, I hope I have answered two of your questions.
Not sure how to do this in sails.js, but I'd like to be able to, when creating a new object on the API, check to see if that object's id exists and if it does, send a 409 conflict response, and if it doesn't, create the object like normal.
For the sake of discussion, I've created a Brand model.
I'm assuming that I would override the create function in the BrandController, search for the brand based on req.param('id') and if it exists, send the error response. But I'm not sure if I'm doing this correctly, as I can't seem to get anything to work.
Anyone have ideas?
I ended up using a policy for this particular use case.
Under config/policies, I created a isRecordUnique policy:
/**
* recordIsUnique
*
* #module :: Policy
* #description :: Simple policy to check that a record is unique
*
* #docs :: http://sailsjs.org/#!documentation/policies
*
*/
module.exports = function(req, res, next) {
Brand.findOne({ id: req.body.id}).done(function (err, brand) {
if (brand) {
res.send(409);
} else {
next();
}
});
};
This allowed me to avoid overriding any CRUD functions and it seemed to fit the definition of a policy, in that only checks one thing.
To tie my policy to my create function, I modified config/policies by adding:
BrandController: {
create: 'isRecordUnique'
}
That's it. Took me way too long to figure this out, but I think it's a good approach.
Well since this is MVC you are thinking correctly that the Control should be enforcing this logic. However, as this is basic uniqueness by the primary id the model should know/understand and help enforce this.
Model should identity the conflict.
In sails the coder is responsible for the defining uniqueness, but I would have the model object do it not the controller.
The controller should route/respond by sending the view which is effectively http 409.
Yes the controller create method should be used in this case, as sails wants to provide CRUD routes for you. Assuming it is a logical create not some resultant or odd non-restful side effect.
I think of Sails.js by default providing a model controller, so use their perspective since you are using their framework. There are many approaches to Control/Model relationships.
res.view([view, options[, fn]])
Ideally the view would control the http response code, the message, any special additional headers. The view just happens to be extremely basic, but could vary in the future.
You could always set headers and response with JSON from the controller but views offer you flexibility in the future, like decoupling, the reason the MVC pattern exists. However, sails also seems to value convenience, so if it is a small app maybe directly from the controller.
I am a beginner and I am creating some forms to be posted into MySQL using Zend, and I am in the process of debugging but I don't really know how to debug anything using Zend. I want to submit the form and see if my custom forms are concatenating the data properly before it goes into MySQL, so I want to catch the post data to see a few things. How can I do this?
The Default route for zend framework application looks like the following
http://www.name.tld/$controller/$action/$param1/$value1/.../$paramX/$valueX
So all $_GET-Parameters simply get contenated onto the url in the above manner /param/value
Let's say you are within IndexController and indexAction() in here you call a form. Now there's possible two things happening:
You do not define a Form-Action, then you will send the form back to IndexController:indexAction()
You define a Form action via $form->setAction('/index/process') in that case you would end up at IndexController:processAction()
The way to access the Params is already defined above. Whereas $this->_getParam() equals $this->getRequest()->getParam() and $this->_getAllParams() equals $this->getRequest->getParams()
The right way yo check data of Zend Stuff is using Zend_Debug as #vascowhite has pointed out. If you want to see the final Query-String (in case you're manually building queries), then you can simply put in the insert variable into Zend_Debug::dump()
you can use $this->_getAllParams();.
For example: var_dump($this->_getAllParams()); die; will output all the parameters ZF received and halt the execution of the script. To be used in your receiving Action.
Also, $this->_getParam("param name"); will get a specific parameter from the request.
The easiest way to check variables in Zend Framework is to use Zend_Debug::dump($variable); so you can do this:-
Zend_Debug::dump($_POST);
Zend framework is built on the top of the PHP . so you can use var_dump($_POST) to check the post variables.
ZF has provided its own functions to get all the post variables.. Zend_Debug::dump($this->getRequest()->getPost())
or specifically for one variable.. you can use Zend_Debug::dump($this->getRequest()->getPost($key))
You can check post data by using zend
$request->isPost()
and for retrieving post data
$request->getPost()
For example
if ($request->isPost()) {
$postData = $request->getPost();
Zend_Debug::dump($postData );
}