royib / clean-architecture-nestjs Goto Github PK
View Code? Open in Web Editor NEWAn in-depth implementation of Clean Architecture using NestJS and type-script
An in-depth implementation of Clean Architecture using NestJS and type-script
Hey @royib, thanks for this repo, this is a very nice starting point for discussion.
I see that use-cases have a dependency on NestJs (like here for example). I expected to only find dependencies on the core entities on this layer and then another layer on top of use-case where framework dependencies starts to appear, but I think something is missing.
Could you expand a bit on the whys of your implementation please? I'd greatly appreciate it!
Hi,
great article but here's the problem I came across while looking through your code. In your MongoDataServices
class you import your Author
, Book
and Genre
from your mongo models but the abstract class IDataServices makes use of Author
, Book
and Genre
that come from entites of the core directory. And these classes are different so my linter cries with errors.
Is this under the MIT license... like nestjs?
I read your article. It's easy to understand for me because of this Github repo.Thank you!
But I have a question about how I can implement transactions with clean architecture.
If you can, it would be helpful for other developers to add example codes using transition.
Hi again,
for some reason I got the following error that comes from the MongoGenericRepository
.
Here's the mongo generic repo:
import { Model } from 'mongoose';
import { IGenericRepository } from 'src/core/abstracts/generic-repository.abstract';
export class MongoGenericRepository<T> implements IGenericRepository<T> {
private _repository: Model<T>;
private _populateOnFind: string[];
constructor(repository: Model<T>, populateOnFind: string[] = []) {
this._repository = repository;
this._populateOnFind = populateOnFind;
}
getAll(): Promise<T[]> {
return this._repository.find().populate(this._populateOnFind).exec();
}
get(id: any): Promise<T> {
return this._repository.findById(id).populate(this._populateOnFind).exec();
}
create(item: T): Promise<T> {
return this._repository.create(item);
}
update(id: string, item: T) {
return this._repository.findByIdAndUpdate(id, item);
}
}
The error is in the get method, here's the whole traceback:
src/infrastructure/data-services/mongo/mongo-generic.repository.ts:18:5 - error TS2322: Type 'Promise<UnpackedIntersectionWithNull<HydratedDocument<T, {}, {}>, {}>>' is not assignable to type 'Promise<T>'.
Type 'UnpackedIntersectionWithNull<HydratedDocument<T, {}, {}>, {}>' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'UnpackedIntersectionWithNull<HydratedDocument<T, {}, {}>, {}>'.
return this._repository.findById(id).populate(this._populateOnFind).exec();
For some reason I don't get it in your code but it arises in mine but the code is identical. Any ideas?
Hi, thank you for your work.
How can I replace mongo with sequelize?
I've created a data-services/mysql/mysql.module following the example of mongo you provided.
However I get a lot of Type errors like:
Property 'findOneById' does not exist on type 'Model<T, T>'.ts(2339)
Can you provide an example?
Thanks
Hi,
Thanks for your article. I noticed that in your core module you are using element from class-validator
and @nestjs/mapped-types
. Does the core module shouldn't use that king of stuff
I have a question regarding entities. I can't see anything regarding Ids in the entities and the create as well as the get endpoints are returning elements of those entities. How can the clients then know which id they need to send to update/ delete for example an author or book?
I assume something is missing and it just works because although typescript does not know about the ids Mongoose returns them with the responses.
Hi, nicely written article, however running the repo as-is according to the README, and I am seeing TypeScript errors.
These might be the same type mismatch errors reported in this issue:
$ npm run start
> [email protected] start
> nest start
src/frameworks/data-services/mongo/mongo-data-services.service.ts:33:55 - error TS2345: Argument of type 'Model<AuthorDocument, {}, {}, {}, any>' is not assignable to parameter of type 'Model<Author, {}, {}, {}, any>'.
Types of property 'bulkWrite' are incompatible.
Type '{ (writes: AnyBulkWriteOperation<AuthorDocument>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }' is not assignable to type '{ (writes: AnyBulkWriteOperation<Author>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }'.
Types of parameters 'writes' and 'writes' are incompatible.
Type 'AnyBulkWriteOperation<Author>[]' is not assignable to type 'AnyBulkWriteOperation<AuthorDocument>[]'.
Type 'AnyBulkWriteOperation<Author>' is not assignable to type 'AnyBulkWriteOperation<AuthorDocument>'.
Type '{ insertOne: InsertOneModel<Author>; }' is not assignable to type 'AnyBulkWriteOperation<AuthorDocument>'.
Type '{ insertOne: InsertOneModel<Author>; }' is not assignable to type '{ insertOne: InsertOneModel<AuthorDocument>; }'.
The types of 'insertOne.document' are incompatible between these types.
Type 'OptionalId<Author>' is not assignable to type 'OptionalId<AuthorDocument>'.
Type 'OptionalId<Author>' is missing the following properties from type 'Pick<AuthorDocument, keyof Author | keyof Document>': title, close, normalize, URL, and 247 more.
33 this.authors = new MongoGenericRepository<Author>(this.AuthorRepository);
~~~~~~~~~~~~~~~~~~~~~
src/frameworks/data-services/mongo/mongo-data-services.service.ts:34:51 - error TS2345: Argument of type 'Model<BookDocument, {}, {}, {}, any>' is not assignable to parameter of type 'Model<Book, {}, {}, {}, any>'.
Types of property 'bulkWrite' are incompatible.
Type '{ (writes: AnyBulkWriteOperation<BookDocument>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }' is not assignable to type '{ (writes: AnyBulkWriteOperation<Book>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }'.
Types of parameters 'writes' and 'writes' are incompatible.
Type 'AnyBulkWriteOperation<Book>[]' is not assignable to type 'AnyBulkWriteOperation<BookDocument>[]'.
Type 'AnyBulkWriteOperation<Book>' is not assignable to type 'AnyBulkWriteOperation<BookDocument>'.
Type '{ insertOne: InsertOneModel<Book>; }' is not assignable to type 'AnyBulkWriteOperation<BookDocument>'.
Type '{ insertOne: InsertOneModel<Book>; }' is not assignable to type '{ insertOne: InsertOneModel<BookDocument>; }'.
The types of 'insertOne.document' are incompatible between these types.
Type 'OptionalId<Book>' is not assignable to type 'OptionalId<BookDocument>'.
Type 'OptionalId<Book>' is missing the following properties from type 'Pick<BookDocument, "title" | "publishDate" | "close" | "normalize" | "author" | "genre" | "URL" | "alinkColor" | "all" | "anchors" | "applets" | "bgColor" | "body" | ... 244 more ... | "evaluate">': close, normalize, URL, alinkColor, and 246 more.
34 this.books = new MongoGenericRepository<Book>(this.BookRepository, [
~~~~~~~~~~~~~~~~~~~
src/frameworks/data-services/mongo/mongo-data-services.service.ts:38:53 - error TS2345: Argument of type 'Model<GenreDocument, {}, {}, {}, any>' is not assignable to parameter of type 'Model<Genre, {}, {}, {}, any>'.
Types of property 'bulkWrite' are incompatible.
Type '{ (writes: AnyBulkWriteOperation<GenreDocument>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }' is not assignable to type '{ (writes: AnyBulkWriteOperation<Genre>[], options: BulkWriteOptions & MongooseBulkWriteOptions, callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], callback: Callback<...>): void; (writes: AnyBulkWriteOperation<...>[], options?: BulkWriteOptions & MongooseBulkWriteOptions): Promise<...>; }'.
Types of parameters 'writes' and 'writes' are incompatible.
Type 'AnyBulkWriteOperation<Genre>[]' is not assignable to type 'AnyBulkWriteOperation<GenreDocument>[]'.
Type 'AnyBulkWriteOperation<Genre>' is not assignable to type 'AnyBulkWriteOperation<GenreDocument>'.
Type '{ insertOne: InsertOneModel<Genre>; }' is not assignable to type 'AnyBulkWriteOperation<GenreDocument>'.
Type '{ insertOne: InsertOneModel<Genre>; }' is not assignable to type '{ insertOne: InsertOneModel<GenreDocument>; }'.
The types of 'insertOne.document' are incompatible between these types.
Type 'OptionalId<Genre>' is not assignable to type 'OptionalId<GenreDocument>'.
Type 'OptionalId<Genre>' is missing the following properties from type 'Pick<GenreDocument, "name" | keyof Document>': title, close, normalize, URL, and 247 more.
38 this.genres = new MongoGenericRepository<Genre>(this.GenreRepository);
~~~~~~~~~~~~~~~~~~~~
src/frameworks/data-services/mongo/mongo-generic-repository.ts:18:5 - error TS2322: Type 'Promise<UnpackedIntersection<HydratedDocument<T, {}, {}>, {}>>' is not assignable to type 'Promise<T>'.
Type 'UnpackedIntersection<HydratedDocument<T, {}, {}>, {}>' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'UnpackedIntersection<HydratedDocument<T, {}, {}>, {}>'.
18 return this._repository.findById(id).populate(this._populateOnFind).exec();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 4 error(s).
Hi, I have some questions
src/core/entities/book.entity.ts
and
src/frameworks/data-services/mongo/model/book.model.ts
Is it possible to merge?
If use typeorm don't need implement IGenericRepository?
thanks
Hi,
I went through your work. Sincerely, I love what you have done so far.
Can you add an env.example file to show the env variables and their types. This will help reduce the complexities involved in using the env variables as the codebase grows.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.