Nestjs: module structure and many-to-many relationships

26 Views Asked by At

A thing that has been bothering me for a while is how to separate related aggregate roots into modules. For example, given a documents and an authors module, and the following endpoints:

  • /documents to list all documents
  • /authors to list all authors
  • /documents/:id/authors to list authors of a document
  • /authors/:id/documents to list documents of an author

How would we separate this into modules? I tend to think about NestJS modules as potentially being their own microservice.

Option 1

  • documents module contains DocumentsController with both /documents* endpoints and DocumentsRepository. The DocumentsRepository has methods list and listAuthorsForDocument(id)

  • authors module contains AuthorsController with both /authors* endpoints and AuthorsRepository. The AuthorsRepository has methods list and listDocumentsForAuthor(id)

This seems wrong, because the DocumentsRepository is purely meant for fetching and saving Document domain objects.

Option 2

  • documents module contains DocumentsController with both /documents* endpoints and DocumentsRepository. The DocumentsRepository has methods list and listByAuthor(id)

  • authors module contains AuthorsController with both /authors* endpoints and AuthorsRepository. The AuthorsRepository has methods list and listByDocument(id)

The documents module provides the AuthorsRepository so that /documents/:id/authors could use the listByDocument method. The authors module provides the DocumentsRepository so that /authors/:id/documents could use the listByAuthor method.

Option 3

  • documents module contains DocumentsController which has the /documents and /authors/:id/documents endpoints and DocumentsRepository. The DocumentsRepository has methods list and listByAuthor(id).

  • authors module contains AuthorsController which has the /authors and /documents/:id/authors endpoints and AuthorsRepository. The AuthorsRepository has methods list and listByDocument(id).

I guess I prefer option 3 as there are no imports between modules but it seems to into NestJSs way of defining endpoints (e.g. a @Controller('/documents') with endpoints @Get() for /documents and @Get(':id/authors') for /documents/:id/authors.

What are reasons to prefer on of these methods over the other or is there a better way?

1

There are 1 best solutions below

0
Ahmet Emrebas On

It does not matter but if you want to be more consistent, here is another idea.

Module A

  • Common Operations

Module B

  • Common Operations

Module AB

  • Relational Operations

This implementation might make your code more consistent.