Migration from Loopback 3 to Loopback 4 - loopbackjs

is there any automated way to migrate project in Loopback 3 to Loopback 4?
For example, I have model definition in JSON:
{"name": "Item",
"base": "PersistedModel",
"forceId": true,
"properties": {
"id": {
"type": "number",
"id": true
},
"created": {
"type": "Date",
"postgresql": {
"dbDefault": "now()"
}
},
"name": {
"type": "string",
"required": true
}
}
}
Is there a way to auto-create the same model in LB4?

Update 13 May 2020
The LoopBack 4 documentation now has a comprehensive migration guide. CLI tooling are also available to help migrate certain compon
Original answer
Hello from the LoopBack team 👋
There is no clear migration path from LoopBack 3 to LoopBack 4 yet. We are discussing different approaches to migration in the GitHub issue loopback-next#1849, you may find some of the information useful. We encourage all LB3 users to join the discussion.
Note that LB4 does not support all LB3 features yet, the list of missing features is maintained in the GitHub issue loopback-next#1920.

As of now there is no way to do such migrations. LB4 is very different in terms of model creation than LB3, in lB3 model configurations were stored in the form of JSON format, whereas, in LB4 is defined in typescript by the means of #model and #property decorators.
May be in future there will be some way.

Related

Is it safe to remove `links.related` from JSON API response? (Ember.js)

Good day,
Does removing of links.related on my JSON response will affect any Ember-Data relationship fetching?
relationships": {
"comments": {
"links": {
"related": "http://localhost:3099/api/v1/articles/1/comments"
},
"data": [
{
"type": "comments",
"id": 1
},
{
"type": "comments",
"id": 2
},
{ ... More comments here ... }
]
}
}
I've read this article : https://thejsguy.com/2016/02/21/handling-nested-resources-in-ember-data.html and this points me to Ember data uses those links internally to fetch the related data so I won't have to access those URLs and make requests to them. I need more concrete opinion before we make any changes to our API.
The related link is used when you don't specify data. Specifying both is redundant.
An example use-case:
You load a lit of blog posts, each has many comments. You don't want to load the comments yet tho. So you specify a relationship with a related link and no data. When the user clicks on the blog post you show the comments. Ember then will automatically load the comments from the specified link.

In Loopback.js, how to query on embedded models?

I'm using MongoDB connector and have a Considerate and Discussion model setup like this:
model-config.json:
{
"Considerate": {"dataSource": "db"},
"Discussion": {"dataSource": "transient"}
}
considerate.json:
{
"name": "Considerate",
"base": "PersistedModel",
"relations": {
"discussion": {"type": "embedsOne", "model": "Discussion"}
}
}
discussion.json:
{
"name": "Discussion",
"base": "Model",
"properties": {
"name": {"type": "string"}
},
"relations": {
"considerate": {"type": "belongsTo", "model": "Considerate"}
}
}
}
How can I query for Considerates based on Discussion's properties? For example, something like this:
Considerate.find({where: {'discussion.name': 'snow white'}})
Inspecting Mongo persisted data, I see that in each Considerate document, there's a _discussion property. Consequently, Considerate.find({where: {'_discussion.name': 'snow white'}}) works. However, this is undocumented and wondering if there is a documented/reliable way to to this.
You can use the filters in the REST APIs wherever you want data from your relations. Eg: [include][relationName]
I think you can also pass data to the fields here.
https://docs.strongloop.com/display/public/LB/Where+filter
This might help you too
https://github.com/strongloop/loopback/issues/517

Can I use non-sequential id for loopback model?

Loopback uses sequential number for model ID. Can I use my own ID generator on server side? How do I go about doing that?
It is possible to specify Loopback generators (guid, uuid, ...) as a default function for id properties in your model definition file.
example with guid:
{
"name": "ModelName",
"base": "PersistedModel",
"idInjection": false,
"properties": {
"id": {
"type": "string",
"id": true,
"defaultFn": "guid"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
As far as I know, you can't specify there your own default function yet. See related github issue.
If you want more advanced behavior (e.g. your own generator), you can create models/model-name.js file and extend a constructor of your model.
Yes, you would need to do a few things:
Set "idInjection": false in the corresponding model.json to turn off automatic id injection
Add the property you want to your model, then set it to be an id either by setting "id": true on the property in the model.json, or selecting the id radial next to the prop in the composer
Generate and inject the id, probably with an operation hook on before save (https://docs.strongloop.com/display/public/LB/Operation+hooks) or maybe a mixin (https://docs.strongloop.com/display/public/LB/Defining+mixins)
If you use Loopback 4 then this is the setting for generating UUID in prime key.
Inside you Model change this.
#property({
type: 'string',
id: true,
defaultFn: 'uuidv4',
})
id?: string;
This is the way to gen a unique id in your table.

Persist Users in Strongloop Loopback

What have you done to persist the User data in production? Is there an easy way to find the schema of the User model so it can be reproduced in a database?
(Preemptive Note: DiscoverSchema finds the schema of the database, not the model)
(Also, I know the docs say the User model can be persisted by setting the file property in the default db datasource, but I have security, scalability, and durability concerns with that.)
setup a database.
define a new datasource by editing the ./server/datasources.json by adding your database, for example:
"mongodb_dev": {
"name": "mongodb_dev",
"connector": "mongodb",
"host": "127.0.0.1",
"database": "devDB",
"username": "devUser",
"password": "devPassword",
"port": 27017
}
Update your ./server/model-config.json to have the built in models use your new datasource :
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"loopback/server/mixins",
"../common/mixins",
"./mixins"
]
},
"User": {
"dataSource": "mongodb_dev"
},
"AccessToken": {
"dataSource": "mongodb_dev",
"public": false
},
"ACL": {
"dataSource": "mongodb_dev",
"public": false
},
"RoleMapping": {
"dataSource": "mongodb_dev",
"public": false
},
"Role": {
"dataSource": "mongodb_dev",
"public": false
}
}
3.Create server/create-lb-tables.js file to move the built-in tables to your database with the following
var server = require('./server');
var ds = server.dataSources.mongodb_dev;// <<<<<<note the datasource name
var lbTables = ['User', 'AccessToken', 'ACL', 'RoleMapping', 'Role'];
ds.automigrate(lbTables, function(er) {
if (er) throw er;
console.log('Loopback tables [' + lbTables + '] created in ', ds.adapter.name);
ds.disconnect();
});
Run the script
cd server
node create-lb-tables.js
This is a link to the official docs about putting built in models on your db
https://docs.strongloop.com/display/public/LB/Creating+database+tables+for+built-in+models
You should persist users into your chosen database via a connector.
The file property is only used to persist data to the filesystem and is NOT recommended for production. For production, you should use one of the connectors (MongoDB, MySQL, etc) to persist your data.
See the docs to find out what properties are part of the built-in User model or change the default database settings to persist the User model to the filesystem to see what properties are available in the JSON file output. If you don't understand all this, go through the tutorial series to get an understanding of all these concepts. Cheers. ;)
Since no one actually shared how to accomplish this, I built this example using the example-mysql repo from strongloop and tweaked 2 files.
model-config.json (change the built-in models from db to your datasource)
bin/automigrate.js (add additional automigrate functions for each model)
See how here: https://github.com/mikesparr/loopback-example-users-to-mysql
Good luck!
Create a persistent(Mongo or any other) datasource using slc loopback:dataSource
Edit model-config.json and mention above created datasource.
Restart server

Loopback 2.4: how to query certain fields of related model via REST API

I have User model over relational DB.
Each User can hasMany "users" where "chiefId" is FK.
"relations": {
"users": {
"type": "hasMany",
"model": "User",
"foreignKey": "chiefId"
},
}
I can query related users for each chief-user like this:
GET /users?filter={"include":"users"}
But it returns full user objects.
How should I query only "name" properties of related users?
Also is it possible to count related instances in one request to server?
A late reply but I just ran into this question now. It is possible:
filter: {
include:{
relation: "users",
scope: {
fields:["name"]
}
}
}
As far as I understood this question is about adding a nested filter on an include level, which seems to be not yet supported: https://groups.google.com/forum/#!msg/loopbackjs/T6onsYMJFOI/V4ILc3Obf3MJ
May be it's not the best way to approach this problem, but what you can do is a manual response transformation in .afterRemote('find', ...) hook.
/users?filter[fields][0]=name
See https://github.com/strongloop/loopback-example-relations-basic for more info.