Sails JS Model Rest API - node.js

I'm new to sails.js and find something strange. I have create a model user like :
sails generate api user
So i have access to :
http://localhost:1337/user/
and
http://localhost:1337/user/create?name=joe&test=true
But why sails allow me to add any fields I want in the model like :
http://localhost:1337/user/create?name=joe&test=true&toto=ok&titi=okToo
toto and okToo are not under my model in api/model/User.js:attributs
I miss something maybe if anyone can help me to understand this.
For me sails.js have to save only fields i put on model:attributs file or throw an exception

You can limit the creation of fields to only those you specific in the model. Sails has this feature to allow for quickly mocking up your site.
http://sailsjs.org/#/documentation/concepts/ORM/model-settings.html?q=schema

Related

How to load a child component of a relation in Strapi

In my Strapi application, I have the following structure:
Footer(single type) > Section(component) > Menu(collection type) > link(component)
When performing a query Strapi only returns the id of the link and I needed its LABEL and URL, does anyone know how I can bring this in a query only?
Strapi section
Link Component
Footer API return
I used this topic on the Strapi forum, but without success yet
https://forum.strapi.io/t/how-do-i-return-only-selected-fields-from-the-model-and-its-relation/1115/2
Disclaimer; im new to Strapi.
The Strapi get requests only populates with relational data in a single layer of nesting. Your links looks to be on the second layer.
You have two options:
Query for the links by ID from your client after receiving the IDs. This can be done efficiently using Promise.all.
Modify the default GET handler for the ressource in the Strapi code. Extend the query to join on your links, and return the response in its entirity.
Update on option 2;
You can customize the logic behind any single endpoint handler in the API in your Strapi backend. The process is best descriped in their documentation on Custom Data Response's. Note that the syntax on how to query the database is based on a popular ORM depending on your database of choice. The ORMs are:
MongoDB (through Mongoose)
Postgres, MySQL, SQLite3 and more (through Bookshelf)
Redis (through ioredis).

Can I change databases on each request (Sails.js)

I have a few PHP scripts which I am in the process of migrating to Node.js. I am using Sails.js for this and I would like to know how I can change databases for each request based on a request parameter.
Currently I have 3-4 identical PostgreSQL databases. Let's just say that each database corresponds to a different client.
Below is a segment of the current PHP script where the database connection is established:
$database = $_GET['db'];
$conn_details = "host=localhost port=5432 dbname=$database user=****** password=******";
$dbconn = pg_connect($conn_details);
Here you can see that the database name is coming from the request parameter "db".
I would like to have a similar functionality in my sails.js controller. I know that i can declare multiple databases in the connections.js and that I can have models use different databases but what i am after is for the models to stay the same and only the database to change based on each request.
I have found 2 similar questions but they have both stayed unanswered for quite some time now. (Here and here)
I think you are looking for something like sub apps
sails-hook-subapps
but it's experimental module. So i wouldn't recommend using it on production. Other option also not good is multiplying your Models like that:
One main model with all methods, attributes and "stuff"
Many models with connections config
In 'parent' model you will select to which model you want to send send action. For example write method:
getModel: function(dbName){
return models[dbName];
}
in models Object you will store all Models with different connections. Not sure how validators will works in this scenario. You need to test if it will not be required do do something like this in child Models
attributes: parentModel.attributes

How to programmatically detach a model from a loopback application?

I am using loopback without the strongloop framework itself, meaning I have no access to any of the cli tools. I am able to succesfully create and launch a loopback server and define/load some models in this fashion:
var loopback = require('loopback');
var app = loopback();
var dataSource = app.dataSource
(
'db',
{
adapter : 'memory'
});
);
var UserModel = app.loopback.findModel('User');
UserModel.attachTo(dataSource);
app.model(UserModel);
/* ... other models loading / definitions */
// Expose API
app.use('/api', app.loopback.rest());
What I would like to achieve is to be able to detach a model from the loopback application at runtime, so it is not available from the rest API nor the loopback object anymore (without the need to restart the node script).
I know it is possible to remove a model definition made previously from the cli:
Destroy a model in loopback.io, but this is not valid in my case since what it does is to remove the json objects that are loaded at strongloop boot, which is not applicable here.
I would appreciate very much any help regarding this, I have found nothing in the strongloop API documentation.
Disclaimer: I am a core developer of LoopBack.
I am afraid there is no easy way for deleting models at runtime, we are tracking this request in issue #1590.
so it is not available from the rest API nor the loopback object anymore
Let's take a look at the REST API first. In order to remove your model from the REST API, you need to remove it from the list of "shared classes" maintained by strong-remoting and then clean the cached handler middleware.
delete app.remotes()._classes[modelName];
delete app.remotes()._typeRegistry._types[modelName];
delete app._handlers.rest;
When the next request comes in, LoopBack will create a new REST handler middleware and rebuild the routing table.
In essence, you need to undo the work done by this code.
In order to remove the model from LoopBack JavaScript APIs, you need to remove it from the list of models maintained by application's registry:
delete app.models[modelName];
delete app.models[classify(modelName)];
delete app.models[camelize(modelName)];
app.models.models.splice(app.models.indexOf(ModelCtor), 1);
(This is undoing the work done by this code).
Next, you need to remove it from loopback-datasource-juggler registries:
delete app.registry.modelBuilder.models[modelName];
Caveats:
I haven't run/tested this code, it may not work out of the box.
It does not handle the case where the removed model has relations with other models.
It does not notify loopback-component-explorer about the change in the API
Update
There's now a function called deleteModelByName that does exactly that.
https://apidocs.strongloop.com/loopback/#app-deletemodelbyname
https://github.com/strongloop/loopback/pull/3858/commits/0cd380c590be7a89d155e5792365d04f23c55851

Data not returned from custom collection

I have a hand-made collection (mymodel) in MongoDB. I have created a sails model+controller using 'sails generate api mymodel'
I am now trying to use the sails find() method using the REST api: http://localhost:1377/mymodel, but I do not get any data returned. I have even tried to write my own end-point method and used the Waterline ORM find() method, but still don't get anything returned.
Am I missing something? Is there something more to be done?
Its a simple model, like {A:123,b:"wf"}
No specific data pieces
From mongo shell, I get the complete information
Found the problem.
If a create a collection using the name "MyModel" in MongoDB, and then create a controller+model in sails.js (sails generate api MyModel), sailsjs does not seem to use the "MyModel" collection, but rather tries to create a new collection completely in lower case ("mymodel") where all the transactions are committed.
So the trick is to create a collection in lowercase only so that sails starts using it
Not sure if this is a bug in sails.js

use Waterline as Standalone (no express)

Good Afternoon,
I am new with node.js and I try to develope an only command app.
For this app I need an ORM and I wish to use WATERLINE as standalone but not in express framework.
I looked at the example and I succeed to see my different collections.
// Our collections (i.e. models):
ontology.collections;
console.log(ontology.collections);
// Our connections (i.e. databases):
ontology.connections;
I am stucked after this. I can't find a way to return my models and make queries.
If someone could help me taht would be great.
Thanks
If you initialized Waterline in the ontology variable and got the collections successfully loaded as you say, now you can access each collection loaded (with loadCollection()) like this:
ontology.collection.mycollection
Where mycollection is the identity defined in your model.
Then you can make queries:
ontology.collection.mycollection.find(...)

Resources