Sails.js, API executing without route configuration and controller.method - javascript

Hey guys here I have a peculiar situation in Sails.js
I created new model and controller named "sponsor" using sails generate api sponsor in the cmd-line
Then I created the route: post /create/new/sponsor' : 'SponsorController.create ,created a method "create" inside the controller and structured the respective model.
Now when am trying it out in postman using legit configuration, everything is working fine, as its is supposed to work. New sponsor is getting created!!
THE PROBLEM IS :
Even when Iam passing URL localhost:port/sponsor new sponsor is getting created (which is supposed to throw status:404) as there is no such route defined.
Then I deleted the controller method "create" and tried using the url localhost:port/sponsor, strange it still works!!!!
The only ERROR that I got is in cmd-prompt saying "Invalid usage of publishCreate():: Values must have an 'id' instead ... (the body passed )"
I checked with the other other APIs that I have created before, everything is working normally according to routes defined ie. if [ url doesnt match route == status:404 ]
I want to know why is it happening?

By default Sails.js has blueprints enabled by default. This automatically creates GET, PUT, POST, Delete routes for your controllers at the url localhost:port/sponsor
See Concepts & Reference for more information.
It is possible to turn off blueprints in sails.js config/blueprints.js, uncomment actions and set it's value to false
actions: false,
Also the index "rest:" of config/blueprints.js needs to be uncommented and set to false to disable the self generated routes ie localhost:port/sponsor
rest: false,
Thank you
#Callum
for pointing out the solution
It's important to realize that, even if you haven't defined these yourself, as long as. A model exists with the same name as the controller, Sails will respond with built-in CRUD. logic in the form of a JSON API, including support for sort, pagination, and filtering.
Best Callum

Related

Ember websocket/new object collision workaround clobbering hasMany promise

I have an Ember 3.8 app that uses Ember Data 3.8 and a websocket. We use the standard Ember Data API to preload data in Routes before processing, and for creating and deleting records. We also push all relevant updates to the database back to the browser through a websocket, where we pushPayload it into the store.
This pattern doesn't seem too uncommon - I've seen people discuss it elsewhere. A common problem with this pattern, however, is how to handle the collision when you are creating a record and the websocket sends down a copy of this new record before your POST resolves. Normally a pushPayload would simply update the record already existing with the payload's ID. For a record mid-save, the pushPayload creates a new record. Then when the POST returns and Ember Data tries assigning the ID to the pending record, it discovers there was already a record with that ID (from the websocket) and throws an exception.
To get around this we wrapped createRecord in some code that detects collisions and unloads the existing record with the ID so the pending record can be the true instance.
This worked well for a while, but now we're getting some odd behavior.
One of the models we create this way is the target of an async hasMany from another model.
Example:
model-parent: {
children: hasMany('model-child', {async: true}),
}
When we have a collision during a save of 'model-child', the PromiseManyArray returned by get('children') is destroyed, but the content of the PromiseManyArray is not. Further, the parent.get keeps returning this destroyed PromiseManyArray. Later we try binding a computed to it, which throws an exception trying to bind to the destroyed PromiseManyArray.
eg:
> modelParent1.get('children').isDestroyed
true
> modelParent1.get('children').content.isDestroyed
false
children: computed('modelParent1.children.[]')
^^^ blows up at controller setup time when trying to add a chainwatcher to the destroyed PromiseManyArray
I've tried reloading the parent object and also reloading the hasMany to get a 'fixed' PromiseManyArray but it still returns the broken one.
I know this is a pretty specific setup but would appreciate any advice for any level of our issue - the websocket collision, the broken hasMany, etc.
I wouldn't know where to being creating a twiddle for this, but if my workaround doesn't actually work I'll give it a shot.

postman: You need to enable JavaScript to run this app

I've got a new API from the backend team in a new project, when I call the api it returns "you need to enable java...", whereas I had used Postman for another project before... is it related to api, server or something else?
I don't think that POSTMAN is capable of executing JavaScript in its console.
Try doing the same in the web browser it will work (You won't see this error message).
I spent some times pondering on this trepidation.. and then suddenly i realized what was going on..
the endpoint does not exist, it could be a misspelling
not in the same directory as you expect it to be,
try adding or removing "/" at the beginning of the url, particularly if you don't specify the hostname, i.e. fetch('getusername') is different from fetch('/getusername') .
. This acceptable in development but NOT when already deployed, it points to different path.
the endpoint may be working fine in the Development,
but somewhere within in the Production/Staging, it generated some exception.
I updated Postman and now it works. I'm not sure if it was because of the update or the restart.
I had this problem with a project built using the new template in Visual Studio 2022 for a React app with .NET Core.
In my case I was only getting the response "You need to enable JavaScript to run this app" with calls to a new controller I added. Calls to the built-in WeatherForecastController were working just fine. My new controller was configured the same as the built-in controller so I could not figure out why this was happening. It has to do with how this project template creates both a React app and a back-end API both accessible on the same port. There's a setupProxy.js file that defines routes that should be forwarded to the API. All other routes are redirected to index.html. This is actually what was happening in my case, because my new controller had not been added to setupProxy.js the middleware was redirecting the request to index.html, and because it came from Postman rather than a browser the message regarding enabling JavaScript is displayed.
The solution is that each controller must be explicitly mapped in setupProxy.js or else it won't be proxied correctly. After making this change it worked perfectly in Postman as well as fetch calls from the React app.
const context = [
"/weatherforecast", // built-in controller than comes with the project template in VS2022
"/recaptcha" // controller I created (this line must be added)
];
While calling the REST API with the postman, if you miss the end-point, then also this issue will come, add the end-point to the URL and check
What worked for me was to turn-off / deselect the user-agent header field under request

this.passthrough() functionality in Ember

I am writing an application in Ember.js and I am also using Ember mirage. I need to make requests to an external server and I am currently trying to set up my config.js file to deal with such requests. Adding this.passthrough() does not work and I still get an error when I try to make my request saying:
"Your Ember app tried to GET 'http://...' but there was no route defined to handle this request. Define a route that matches this path in your mirage/config.js file. Did you forget to add your namespace?
I believe this should be a simple thing to fix, any ideas of what is going wrong?
Mirage helpdoc explaining it detail. configuration/#passthrough
If you want all requests on the current domain to pass through, simply invoke the method with no arguments:
this.passthrough();
You can also allow other-origin hosts to passthrough. If you use a fully-qualified domain name, the namespace property will be ignored. Use two * wildcards to match all requests under a path:
this.passthrough('http://api.foo.bar/**');
Note:Put all passthrough config at the bottom of your config.js file, to give your route handlers precedence.

Why does my Sails.js app have a route I never added

I have created a new Sails app, and so far I have created an api using sails generate api guitar, and then added this code in the controller:
module.exports = {
fender: function(req, res){
console.log(req.params);
res.notFound();
}
};
As expected, when I go to http://localhost:1337/guitar/fender I get a 404 error (that's the response I programed). But what I don't get is, if I go to http://localhost:1337/guitar/fender/4, the console will show [ id: '4' ]. I seems that somewhere there's a GET /guitar/fender/:id (using Express/Rails syntax here) sort of URL. But I don't see it anywhere, not in config/routes.js or anywhere else.
So, does Sails.js create a :id for every controller action automatically? Or am I missing something here?
I tried some things, such as adding this to the config/routes.js file:
'get /guitar/fender/:brand': 'GuitarController.fender'
And then when I go to the URL again, [ brand: '4' ] will be printed instead of id.
So my final question is: Does Sails.js automatically make an :id for every controller action?
(I couldn't find this on the docs either)
To speed up REST development, Sails uses an internal API called Blueprint.
When you run the "generate" command, Sails creates for you all CRUD operations to handle your entity, so you can immediately test your API without any code.
Here you created a guitar entity. Now you can play with it directly in your web browser! Let's try this on localhost:
/guitar/create?name=Ibanez
/guitar
/guitar/4
/guitar/update/4?name=Stratocaster
/guitar/4
/guitar/destroy/4
/guitar
If you want more information about Blueprint, you can:
Read this section from Sails documentation
Take a look at the config/blueprints.js file in your Sails project

With Sails.js how can I make /users/me a route that works with associations?

I have a main model Accounts, then I have a few Has Many models like Notifications and Friends
In my main.js
I'd like to be able to do things like:
socket.get('/users/me/notifications');
instead of like:
socket.get('/users/ + g_userAccountId + '/notifications');
^^ That works for right now, but it is set asynchronously so if any code loads before g_userAccountId is set it will try to use undefined instead which is bad.. Very bad..
I understand policies and all that I'm just wondering how I can make this work with the REST blueprints and what not. If I'm not clear please let me know
Is there a way to do this without setting findOne methods in each controller? Like to automatically fill in /me/ with 1
The easiest way I can imagine doing this without setting findOne methods in each controller would be to create a policy that matches the /users/me/notifications route, redirecting it to the current session's user id. You could potentially use something like the following, and update the /config/policy file.
if (session.authenticated) {
return res.redirect('/users/' + req.session.user.id + '/notifications');
}
If you wanted to do something to handle anytime the /users/me route is hit, you could modify this policy, tweak the req.url and redirect to the new one that uses the user ID, and apply it to all relevant routes in policy config file, or setup a custom middleware to handle the problem the same way.

Categories

Resources