Can I register micro-frontends lazily after invoking start method from single-spa framework (framework used for microfrontend apps)? - micro-frontend

My requirement is to register apps on dynamic routes (I need to get a UUID from server & append it to every MFE route). My approach is to first register a single MFE, get the UUID from server & then register other MFEs on dynamic routes. Is it possible to register MFEs after invoking start() method on the same single-spa instance ? If no , can I register those MFE's on another single-spa instance ? Will this impact the single-spa behaviour ?

Related

How can i use same session variable in multiple controller services in sails.JS?

I am newly initiated backend devloper. I am working with sailsJS [MVC Framework of Nodejs].
I am having one confusion regarding session access and flow in sailsJS. Please help me to clear this.
I am saving my user in session in AdminController, which i had create using CLI service of sailsJS. But I am not able to use that variable in another controller : InventoryContoller in the same application.I was in impression that session is something that we can use in whole application from anywhere.
I created session in one of app controller : AaminController as follow:
req.session.user = user;
But i am not able to access this session variable outside the AdminController.
I want to use this variable inside whole applicaiton.

Environment specific configuration of datasources in loopback4 application

I have just started my first loopback project and chosen loopback4 version for the application. Its purely a server application which will interact with databases (Redis and mongodb) and will call external API services due to micro-service architecture.
Now, I have 3 datasources in my application i.e. mongodb, Redis, and REST based datasource to call external services. I am facing 2 problems in going forward.
1. Environment specific configurations of Datasources: I need to maintain configuration for all three datasources according to the NODE_ENV environment variable. For lb3 i found this solution,
https://loopback.io/doc/en/lb3/Environment-specific-configuration.html#data-source-configuration
which does not work in lb4. One solution is to add configuration files having names mongodb.staging.json and mongodb.production.json and same for redis and rest datasources in directory src/datasources, and load this config according to NODE_ENV variable using if condition and pass it to the constructor of datasource. It works but it does not seem nice, as it should be application's responsibility to do this.
Can somebody suggest me lb3 equivalent solution for the above?
2. Calling External APIs via datasource: in lb4, To call external services its recommended to have a separate REST based datasource and its service to call it via controller. Now, In REST datasource config, one has to define a template of all the API calls which will happen to the external service https://loopback.io/doc/en/lb4/REST-connector.html#defining-a-custom-method-using-a-template.
As my application calls external service heavily with relatively large number of request parameters. It becomes really messy to declare each API call with its request params and to maintain this in the datasource config which will be environment specific.
Can somebody tell me a more robust and cleaner alternative of the above problem?
Thanks in advance!!
Using environment variables in datasource configs
The datasource config is simply a JSON file that's imported in into *.datasource.ts. Hence, you can replace that JSON file with a Typescript file and import it accordingly. LoopBack 4 does not provide any custom variable substitution mechanism. Instead, it is recommended to use process.env.
Recent CLI versions replace the JSON config in favour of using a single Typescript file:
import {inject} from '#loopback/core';
import {juggler} from '#loopback/repository';
const config = {
name: 'db',
connector: 'memory',
};
export class DbDataSource extends juggler.DataSource {
static dataSourceName = 'db';
static readonly defaultConfig = config;
constructor(
#inject('datasources.config.db', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
The dependency injection in the constructor allows you to override the config programmatically via the IoC container of the application.
Further reading
https://loopback.io/doc/en/lb4/DataSources.html
Calling external APIs without REST connector
The REST connector enforces a well-defined interface for querying external APIs so as to be able to do validation before sending out the request.
If this is not favourable, it is possible to create a new Service as a wrapper to the HTTP queries. From there, you can expose your own functions to handle requests to an external API. As Services do not need to follow a rigid structure, it is possible to customize it to your use-case.
It is also possible to create a new request directly inside the controller using either built-in or external libraries.
Overall, there isn't a 100% right or wrong way of doing certain things in LoopBack 4. Hence why the framework provides numerous ways to tackle the same issue.

How do I invoke a Sails.js controller function from a file in the project root?

I am building a Sails.js application that runs on Heroku. I need to use Heroku Scheduler to run a "CRON" job every few hours. The scheduler only allows me to run a single command so I have it setup to run $ node sendEmails.js every 1 hour.
The issue is, sendEmails.js is not a part of the core Sails.js project and I need it to invoke a function inside my ReportsController.js file. How exactly do I go about doing this? I don't want to copy the controller logic to sendEmails.js because it has a lot of dependencies to the database and other services which I can't duplicate. For context:
/**
* ReportsController
*
* #description Server-side logic for managing reports
* #help See http://sailsjs.org/#!/documentation/concepts/Controllers
*/
module.exports = {
// I need to call this function from sendEmails.js which is in my project root
generate: function(req, res) {
// Logic for generating reports
}
}
You can do this in several ways:
(Better) Create a service and then invoke the service name like Myservice.myfunction or even sails.myservice.function. Your service, as the name says, will be available for every controller and can be used to centralize code that will be used globally. Take a look : Sails Services. You can then invoke your service inside a controller, then your service can (or cannot) do option 2 if it suits you.
(Not very good) Inside a controller or service, do a manual require for the path of your file. Like this let myfunctions = require('../folder/myfile.js') and then invoke the functions like ``myfunctions.myfunction(nargs). Don't forget to usemodule.exports = {...}`.

Feathers JS nested Routing or creating alternate services

The project I'm working on uses the feathers JS framework server side. Many of the services have hooks (or middleware) that make other calls and attach data before sending back to the client. If I have a new feature that needs to query a database but for a only few specific things I'm thinking I don't want to use the already built out "find" method for this database query as that "find" method has many other unneeded hooks and calls to other databases to get data I do not need for this new query on my feature.
My two solutions so far:
I could use the standard "find" query and just write if statements in all hooks that check for a specific string parameter that can be passed in on client side so these hooks are deactivated on this specific call but that seems tedious especially if I find this need for several other different services that have already been built out.
I initialize a second service below my main service so if my main service is:
app.use('/comments', new JHService(options));
right underneath I write:
app.use('/comments/allParticipants', new JHService(options));
And then attach a whole new set of hooks for that service. Basically it's a whole new service with the only relation to the origin in that the first part of it's name is 'comments' Since I'm new to feathers I'm not sure if that is a performant or optimal solution.
Is there a better solution then those options? or is option 1 or option 2 the most correct way to solve my current issue?
You can always wrap the population hooks into a conditional hook:
const hooks = require('feathers-hooks-common');
app.service('myservice').after({
create: hooks.iff(hook => hook.params.populate !== false, populateEntries)
});
Now population will only run if params.populate is not false.

How to inject data into Angular2 component created from a router?

I'm currently trying to build an Angular2 prototype (based on alpha44) of our Angular1 app (pretty complex one) and I'm trying to find the best model/data architecture when using routes and child routes.
In my example, from a child component created from a route, I want to access a property of the parent component (hosting the router-outlet).
But when you create a component from a router-outlet, you cannot use #Input and #Output anymore.
So what is the best practice to inject some data/properties, except basic routeParams and static routeData?
How do you communicate with the parent component without too much coupling?
You can use RouteData in order to pass data into routes. See here and here. I'm still missing the part of initialising this data obj from the component (see my question regarding)
A shared service can be used with components added by the router. For details see https://angular.io/docs/ts/latest/cookbook/component-communication.html
data support also was added to the new router in RC.4. For details see How do I pass data in Angular 2 components while using Routing?
Angular 2 - equivalent to router resolve data for new router might also be related.
You can pass (inject) data from child component inside Router Outlet to Parent component with Subject,Observable. You can found my solution in this video.
See the code on GitHub: https://github.com/tabvn/angular-blog

Resources