How to get metadata from MongoDB with Breeze - node.js

Currently I have a project using WebAPI and EF with Breeze, it works fine with Metadata stuffs for validation on server but when migrating to NodeJS and MongoDB, I get stuck for trying get Metadata from MongoDB. I checked out zza BMEAN app but I just saw on this project:
app.get('/breeze/Breeze/Metadata', getMetadata);
function getMetadata(req, res, next) {
next({
statusCode: 404,
message: "No metadata from the server; metadata is defined on the client"
});
}
I also read all document about Breeze/MongoDB but still doesn't help me to get Metadata for this.
The main point is I just want to change backend with BMEAN instead of WebAPI+EF+Breeze, don't need to change code on client.
Thanks

The metadata is provided by EF, not by MongoDB. If you are using a CodeFirst approach with EF then you should already have a DBContext.
This talks about how to use the DBContext -
http://www.breezejs.com/documentation/entity-framework-dbcontext
This talks about how to use EF as a design tool to build your meta data from classes -
http://www.breezejs.com/documentation/ef-design-tool
Odds are you already have what you need to generate the metadata it is just extending that and exposing a service to provide it to the client.

PW Kad's answer is correct, but to clarify, there is no way to get metadata from a MongoDB database because the database itself has an indeterminate structure. So you have to tell your client what the structure is. If you want to use the same client code for EF and Mongo then saving the metadata provided by the EFContext in your Mongo project makes a lot of sense. In other cases simply define the metadata directly on the client via Breeze's metadata api calls.

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 a Node package require a DB connection?

As per the title, can a Node.js package require a database connection?
For example, I have written a specific piece of middlware functionality that I plan to publish via NPM, however, it requires a connection to a NoSQL database. The functionality in its current state uses Mongoose to save data in a specific format and returns a boolean value.
Is this considered bad practice?
It is not a bad practice as long as you require the DB needed and also explicitly state it clearly in your Readme.md file, it's only a bad practice when you go ahead and work without provide a comment in your codes or a readme.md file that will guide any other person going through your codes.
Example:
//require your NoSQL database eg MongoDB
const mongoose = require('mongoose');
// to connect to the database. **boy** is the database name
mongoose.connect('mongodb://localhost/boy', function(err) {
if (err) {
console.log(err);
} else {
console.log("Success");
}
});
You generally have two choices when your module needs a database and wants to remain as independently useful as possible:
You can load a preferred database in your code and use it.
You can provide the developer using your module a means of passing in a database that meets your specification to be used by your module. The usual way of passing in the database would be for the developer using your module to pass your module the data in a module constructor function.
In the first case, you may need to allow the developer to specify a disk store path to be used. In the second case, you have to be very specific in your documentation about what kind of database interface is required.
There's also a hybrid option where you offer the developer the option of configuring and passing you a database, but if not provided, then you load your own.
The functionality in its current state uses Mongoose to save data in a specific format and returns a boolean value. Is this considered bad practice?
No, it's not a bad practice. This would be an implementation of option number 1 above. As long as your customers (the developers using your module) don't mind you loading and using Mongoose, then this is perfectly fine.

Couchdb2 mango/find js api

I have noticed that all the couchdb api helpers don't implement Mango query
I have found cradle started working on it, but seems they stoped implementing, nothing on docs about it.
https://github.com/flatiron/cradle/blob/master/lib/cradle/database/mango.js
Is there a good js api that supports mango find?
Secondary: Is there a reason why no one seems to be implementing mango query, why is everyone sticking to map/reduce?
Based on the comments give, I would like to clarify my question:
I know about pouch-find, but I presume this is for local storage or local instance of pouch that could be found in browser or nodejs, but I want to find a library that I can use to query couchdb database on the server.
I have found a temporary solution for now. Im using cradle with query function
ex:
db.query({
method: 'POST',
path: "/_find",
body: {
selector:{"_id": "settings/12345" },
limit:1,
//use_index: "_all_docs"
}
}
So to further explain my setup. Im using one couchdb per user. That db will sync to browser using pouchdb, I can use pouch-find to query that synced local copy (Is this correct?).
But then I have other couch databases that are not synced, that can be accessed by many users. To query these databases I use cradle with the above example.
You can find pouchdb-find here which is in development. If there is no api helpers for Mango Query yet, it's probably because it`s new altough cloudant had this query language since a moment.

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

Do I have to add loopback-component-passport's core models manually?

I installed loopback-component-passport so I can use it with strongloop's Loopback framework. I followed the docs,
but after this command: npm install loopback-component-passport, the following files/models are not created:
UserIdentity model
UserCredential model
ApplicationCredential model
These files are used by Loopback for third-party authentication. Do I have to add them manually? Or am I doing something wrong?
Yes, you have to add them manually. You can refer this example, loopback-example-passport on github.
The reason is the relationships of loopback-component-passport's core models i.e UserIdentity model, UserCredential and ApplicationCredential with Loopback's core model AccessToken and User doesn't come preconfigured which is required for authentication.
Also, you might notice that the developer extended the models but didn't added any model.js. This is so because there was no need to add any runtime logic. For starters, you might want to extend the core models as per the example and create relationship and acls only. Then you can proceed with custom logic.
I think loopback built in models stay tucked away in node_modules, so assuming you mean that these tables are missing from your datastore, you can do an autoupdate in order to get loopback to build any missing tables.
I add the following code to a file in the server/boot directory when I need to during development.
module.exports = function(app, done) {
app.datasources.mysql_db.autoupdate(function(err) {
if (err) throw err;
console.log("autoupdate");
done();
})
}
Where mysql_db is the name of your datastore.
This will update the datasource when the server boot but shouldn't drop existing data (saying that I have seen instances where foreign keys are lost, so care & db backup is still needed).

Resources