In almost every application there is a file where we throw all our application endpoints. If you are working with Angular, it probably looks something like this:

At first glance, everything looks fine, but as the application grows, so does this file, creating a couple problems.

We are violating the one single responsibility. We are exposed to merge conflicts, our endpoints are not portable, and it becomes difficult to find the endpoint location in the file.

We need to assign responsibility to the module in charge, so each module is responsible for exposing its endpoints.

Then we can aggregate and join the entire endpoints in our API service.

Let’s see how we can do this with the help of Angular Dependency Injection and the multi option.

Create the API Service

First, we need to create the service responsible for performing aggregation and expose application endpoints.

api.service.ts

We have an InjectionToken that will represent each endpoint. Now let’s see how we can fill the END_POINTS token.

Create the Auth Module

Each module needs to create two additional files.

auth.api.ts

As the name suggests, this file will be responsible for the Auth endpoints.

auth.d.ts

We still want to use the power of typescript by leverage typescript declaration merging.

At the most basic level, the merge mechanically joins the members of both declarations into a single interface with the same name.

Now, typescript will merge each endpoint to the EndPoints interface so that we can get auto-completion.

Next, we provide the Auth endpoints to Angular DI in the corresponding module, which in our case is the Auth module.

auth.module.ts

You can think of the multi option as an array. Each time we add a new provider, Angular pushes the provider into the array.

So if we go back to our API service and log the _endpoints property, we will see we have one item in the array — the Auth endpoints.

END_POINTS Provider

Great, now we just need to flat our endpoints to one big object.

api.service.ts

Finally, let’s create a simple method that will help us to resolve the url.

api.service.ts

Now, we can use the API service in every service we need. For brevity, I’ve already added a Todos module with the same process we described.

For example: