Querying the Database from Angular
One of possible improvements is to perform queries against MongoDB directly from Angular Universal. In this lesson you will create a service which does this job.
Generating the service#
Start your work by generating a new service that will be used to connect to MongoDB:
To apply the Don't Repeat Yourself (DRY) principle, you will utilize this service in the api.ts file. In other words, you will move the database querying logic from api.ts to
MongoService. A naive implementation could look like this:
The prepared class can now be imported into api.ts instead of the current MongoDB-related logic. Unfortunately, this is not trivial. Try to inject the prepared service anywhere in your application, such as
Now run the Angular compiler:
Take a look at the content of the dist/browser/main***.js bundle that is sent to the end user's browser:
That's a severe security breach: you disclose your database connection string to every user of your application!
Angular Universal is an excellent solution as it enables sharing the code base between browser and server bundles. While it's a great way to avoid duplicating business logic in your project, it might lead to serious security breaches and compromising sensitive data such as database connection strings!
isPlatformServer() methods doesn't help here because the same code base is still used on both platforms. This is how the
isPlatformXXX() method used in
As you can see, the server-specific code branch is still present in the browser bundle.
Moreover, the connection string may change in the future. Do you want to rebuild your application because a variable value has changed? You probably don't.
Providing secrets to server-side Angular#
ngExpressEngine that we use to render Angular views can provide additional injection tokens to the Angular application. You could provide Angular with a connection string and use it to set up a database connection. However, that would lead you to another pitfall: a database connection would be set up every time a user accesses the application. Instead, it would be better to provide Angular with an already instantiated connection and inject it into
MongoService using Dependency Injection.
First, let's export the
dbClient object from api.ts:
Next, adjust the statement that imports from api.ts into server.ts: