Model in Node/Express - node.js

In a typical MEAN stack application, the server side have Model, View and Controller, where the Model represents the mongoose model. Suppose that, the application does not access to database directly, rather it is accessing the database via RESTful API, is there any model representation in this case? If yes, what is the model representation?

There are various processes which run sequentially when we do some kind of operation using mongoose. Calling statics, methods, data validations, pre-save hooks are some of them. Now, for a REST API accessing DB there are ways to create these processes.
Let's say we are doing operations on users -
Create a service which can validate all the data of a particular user (req.body) using a validator such as validator.js
Create methods in that service which can serve as statics or methods same as they are created in a mongoose model
You can also create pre-save hooks (method which is always called, like hashing password) if necessary before sending your data through the REST API
It is possible to create multiple services to validate and modify data as and when necessary in a very nice way by calling them in an order at your route middleware.
For example -
router.post('/users', [
RestService.getUserById,
UserService.checkForDuplicateUser,
UserService.validateData,
UserService.preSaveHook,
RestService.saveUser
]);
So in this way a model representation can be created.

Related

How to use Node.js in Postgraphile mutations?

I am making an application that shows information about different users, which is taken from third party API. I save this information in my own format with multiple tables in PostgreSQL to keep track of any changes to the data and provide history of changes (third party API only provides current data).
I want to use GraphQL, specifically Postgraphile to simplify backend development. But there is one use case which I can't find a way to implement with Postgraphile. Here is what I want to implement:
User wants to see an updated information
GraphQL mutation query is sent to the server, something like this:
mutation UpdateUserData($userid: Int) {
updateUser(id: $userid) {
field1,
field2,
relatedObjects {
field3,
filed3
}
}
}
Server makes an API request to third party server, processes data, makes some calculations and updates the database
Requested fields are returned to client
I know that this type of custom mutations can be implemented with database functions like PL/pgSQL or PLV8, but they can't make http requests and I already have most of the logic for data processing in Typescript, so would like to use it.
Is there a way to create a custom mutation that will call JavaScript function which has access to Node.js modules, interfaces and classes that I already created?
One solution that I think will work:
Call REST endpoint on my server, like /update_user?id=$userid
User data is loaded from third party API and database is updated
Client receives response, like Update successful
Normal GraphQL query is called to get the data
Is there a better way of satisfying this use case?
This part is a bit hidden in the documentation, but the easiest way to add mutations written in JavaScript is the makeExtendSchemaPlugin.
Here you can define type definitions in SDL and implement resolvers in JS.

Mongoose Sharing Validation/Pre-Save Methods Across NodeJS Apps

If one Nodejs app connects to a Mongo instance, and that app has defined a User schema with pre-save hooks, validation, etc.
And then another Nodejs app connects to the same database, and tries to register a User schema with different properties.
And then the second app saves a User
What happens?
I'm confused with how two Nodejs apps may communicate to the same database.
For example, it's very easy to see how one might want to have V2 of an api on a separate nodejs app developed by a separate team. But they will plug it into the same database and use the same Schema (or will they?), and I'm confused with how things are shared between the two apps.
Any help clarifying this in best-practices would be appreciated
I believe I've found the answer in the Documentation.
This connection object is then used to create and retrieve models. Models are always scoped to a single connection. docs
And
Models are fancy constructors compiled from our Schema definitions. docs
Which explains that a DB Connection 1's Schema Definitions (pre-save, etc), do not affect DB Connection 2's writes/etc.
Essentially, they are completely independent of validation and everything else. They only need to be OK in their own context.

Switch Databases dynamically

I'm doing a POS(point of sale) as Saas with React in the frontend, NodeJs in backend(API Rest) and MongoDB as the database.
I've finished a basic program and now I want any user is registered will have his own database.
After read some articles and question on the internet my conclusion was switch between databases each time the frontend consume the backend(API).
General Logic:
User Log in
In the backend, I use a general database to check user credentials and also I acquire the name of the database of this user.
Each time the frontend consumes the API the next codes are executed in a middleware to know what database should use the API:
var dbUser = db.useDb('nameDataBaseUser');
var Product = dbUser.model('Product', ProductSquema);
I have the schemas and the variable 'db' defined fixed in the code:
var db = mongoose.createConnection('mongodb://localhost');
Problem:
I don't know if is the correct solution about what I am trying to make, but it seems me inefficient that the model is generated constantly each time the API is called, because in some API(i.e in some middlewares I have until 4 different models)
Question:
This is the best way? or any suggestion to face this problem?
Not sure about the idea of creating a new db for each new user. That seems to create a lot of complexity and makes it difficult to maintain, and makes it difficult to access the data for analytics and such later. Why not use a new collection per new user? That way you can use just one set of db access credentials. Furthermore, Creating a new collection happens automatically when you store data for it.

Sail.js - how to structure JSON based live data output with existing static data in the model

In my Angular app, I want to display a table which contains the following
a) URL
b) Social share counts divided by different social networks
Using Sails.js, I already have the api created for the URL when the results show up, I can display the URL now I'm confused how to get the appropriate social counts showing right besides
Here's the API I'm using: https://docs.sharedcount.com/
by itself, I can see the JSON it produces
But here are my questions:
Should I create a new api (model/controller) for social count data or include it in my model where I have the 'url' action defined?
If I create a new api or include the social_counts as an action in the current, what would my JSON query look like? to retrieve the URL's, I'm using default API blueprint that Sails provides, so:
http://www.example.com/url/find?where={"title":{"contains":"mark"}}
Struggling a bit in terms of the thought process, would be great to get input on this
It depends on your app. is your app will store that data or just consume it? If it need to store, of course you need the API. In purpose for modification or aggregating the data for example.
No, you can't do that. That shortcut method only works if you have the data in your database and let the Sails Waterline ORM and Blueprint API served it.
Perhaps, if you only need to consume the data from that Sharedcount API, you didn't need to use Sails as a backend, in this context. Just use Angular as a client of that API. Except if you need to modify the data first and store it in your own database, so Sails will helps with it's Waterline ORM and Blueprint API.

Sequelize REST API generator

I am developing a Nodejs application and my database is Postgres and I am using Sequelize as my ORM because of its excellent support for migrations.
I am on the lookout for a good REST API generator based on the schema I have defined. There are two main hurdles I am facing and they are that the generators don't do a good job of creating association API routes and lack of ACL support.
On the associations front, my schema has multiple levels of association i.e. for example..
Student.hasMany(Courses);
Courses.hasMany(Subjects);
So ideally the generated REST API should be something like
/student/:student_id/course/:course_id/subject/:subjectId
I found a few projects that are doing this, but are incomplete.
https://github.com/sequelize/sequelize-restful - is good but does not have ACL support
https://www.npmjs.org/package/restizr - is in alpha stage and does not generate API routes for associations.
Is there any module that supports this?
What you were doing here is writing a webservice without a domain model. https://en.wikipedia.org/wiki/Anemic_domain_model Ofc. you have every right to do it, but I wonder if you really understood what a webservice means. https://stackoverflow.com/a/1530607/607033 It is not a database with CRUD HTTP interface normally, though nowadays it is popular doing something this way and call it REST. A response to a REST HTTP request is a viewmodel https://softwareengineering.stackexchange.com/a/425001/65755 and it contains not just data, but a lot of metadata and hyperlinks. A REST API is a special type of webservice with many constraints. https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf http://www.markus-lanthaler.com/research/hydra-a-vocabulary-for-hypermedia-driven-web-apis.pdf Your ORM is used 2 layers deeper in the data layer and it has nothing to do with the presentation layer where your REST API should be. I really wonder why people are making applications, which are doing nothing except serving data directly from the database and use the most inconvenient technology to do it. I guess there are databases nowadays with ACL and REST API support, so all you need is just using them. https://learn.microsoft.com/en-us/rest/api/sql/ Or there was something for PgSQL and Nodejs too around the time you asked this. https://github.com/QBisConsult/psql-api

Resources