nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.9k stars 7.55k forks source link

Share Libraries with front end, Angular or Aurelia? #275

Closed BringerOD closed 6 years ago

BringerOD commented 6 years ago

First, great job on this project!

We are in the middle of a proof of concept using nestjs and we are wondering if anyone is sharing code/libraries on the front and back end?

We are building a pretty intense workflow engine that runs offline as well as on the server and we don't want to repeat ourselves. Basically the domain model, the main logic and rules, can run on either the front or the back.

Has anyone done this? What is your build process?

wbhob commented 6 years ago

My to-do list includes making an Angular Universal implementation for Nest.

gejustin commented 6 years ago

I attempted something similar once using Angular as a backend framework as well as a front-end framework. In order to share services in both contexts, I had to make sure that I properly configured dependency injection for both applications.

It's important to remember that you will be running two separate applications, they will each have their own DI and they will only be sharing raw source code and not necessarily concrete class implementations.

You will need to define modules/providers for each shared service you want to use in both contexts and make sure that everything those classes depend on is also provided.

For example:

export class CustomerRepository { 

    constructor(private httpClient: HttpClient) { }

    public getById(id: number) { 
        return this.httpClient.get(`http://example.com/customers/${id}`).map(res => new Customer(res));
    }
}

This is a trivial example, but lets pretend you want to share the CustomerRepository class on both the server and front end in two different frameworks. Because nest is heavily inspired by Angular, the providers will look very similar, but in other frameworks you'd have to follow their way of providing things to the DI Container.

// Configure DI for Front-End in Angular
// Add this provider to an Angular Module's providers metadata
const nestCustomerRepoProvider = { 
    provide: CustomerRepository,
    useFactory: (httpClient: HttpClient) => new CustomerRepository(httpClient),
    deps: [HttpClient], // Front-end implementation of an Http Client (probably Angular's HttpClient in this case)
}

// Configure DI for Back End in NestJS
// Add this provider to a Nest Module's components metadata
const nestCustomerRepoProvider = { 
    provide: CustomerRepository,
    useFactory: (httpClient: HttpClient) => new CustomerRepository(httpClient),
    inject: [HttpClient], // Back end implementation (probably custom in order to maintain the same interface)
}

In this case, you will probably need to also provide a different implementation of the HttpClient interface because it will most likely work differently in node vs browser, but as long as the interface is the same the CustomerRepository works in both.

kuncevic commented 6 years ago

@wbhob the nest universal thing is just being done here https://github.com/EreckGordon/angular-universal-pwa-starter but sounds like you are talking about some sort of nestjs middleware?

BringerOD commented 6 years ago

@gejustin, thanks for the insight here. Great examples. I am working on a POC to test this out.

wbhob commented 6 years ago

Yes I am referring to a plugin.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.