Type |Â Version
---|---
Question | -
Hi @Romakita.
I've been using this framework about 3 month on production service.
I am very satisfied. This framework makes very easy and scaleable development.
But I just found https://github.com/nestjs/nest framework and it looks very similar with your framework.
I wonder what is next plan on this framework and difference between nest and this.
Thank you.
from ts-express-framework lover.
Hi @jindev,
Thanks for this project example. Nestjs is awesome :D
To answer you, Ts.ED has the same approach. I've look on Angular to build this framework (like DI, Controller, etc...). Ts.ED is decorator oriented, Nestjs provides less (maybe is a better approach XD).
Features comparison:
Core features | Ts.ED | Nestjs
---|---|---
Lifecycle | yes | no
Module | no | yes
Controllers | yes | yes
Services | yes | yes
Factory |Â yes | yes but not found example
Middlewares | yes | yes
HttpExceptions | yes | yes
Converters | yes | No
Model | yes | yes
Pipe | yes | yes
Auth | yes | yes
Guard | no | yes
JsonSchema | yes | no
Custom decorator | yes | yes
Interceptor | no | yes
Extra features | Ts.ED | Nestjs
---|---|---
Validation | yes | no
Swagger | yes | no
Socket | yes | yes
GraphQL | no | yes
I've in mind some feature for the future of Ts.ED:
@tsednpm scope. (Example: @tsed/core, @tsed/di, @tsed/core, @tsed/ajv, etc...).All of this need a time to work on and any help are welcome ;)
I hope this answer help you to see the Ts.ED future and the difference between Ts.ED and Nestjs (or not).
See you,
Romain
Thank you for replying!
It help to know what is differences! and future of Ts.ED.!
I think it could be better if Ts.ED support DAO, DTO or VO!
Hope Ts.ED is getting better!
See you
jindev
@jindev ,
I'm not familiar with DAO, DTO or VO.
Ts.ED have a Model feature with the JSONSchema https://romakita.github.io/ts-express-decorators/#/docs/jsonschema. Maybe it's similar ?
@Romakita
JSONSchema is used for
Converters for serialization/deserialization,
Swagger for the documentation,
AJV for the model validation.
But I think a production project getting bigger, it needs DAO/DTO/VO that separate logic/concern not only validation.
Project structure looks like below when I create it as a production.
I think that is a time to create VO model if 'userService' is getting bigger and has a lot of logics like validate user or other data that even not concern in services.
Hi @Romakita and @jindev
I definitely agree that the data representation at the different layers of the application is what is giving the most headaches. I have worked too long on projects that had DAO/DTO/VO representations to find that attractive :-)
I find that Plain javascript Objects represented with typescript interfaces is the most attractive way to represent data. These raw data objects can then be passed to services for any business logic.
The problem currently is that the data entering the Controllers are TsED Model objects which do not necessarily behave further downstream.
Maybe TsED should adopt the toObject and toJSON for Model objects that are available on Mongoose Documents?
Maybe it could even be possible to define that you wish only the plain object (toObject) to reach your controller function? All incoming conversion/validation/swagger has been done so the Model itself is no longer needed when crossing the controller trust boundary?
class User implements IUser {
@Property()
name: string;
...
}
@Post('/')
@Returns(User)
async create(@BodyParams() @Schema(User) user: IUser): Promise<IUser> {
// You know that the object has been validated against the User schema
// so the interface representation should be trusted
// <<< here user is plain javascript object implementing interface IUser
}
When going back out (across the boundary) the serializer can pick up the correct Model again using the @Returns definition!?
Why am I concerned?
Well, I have a custom serialiser for my DB (thanks to @Romakita) to make sure that the TsED Model objects get inserted correctly into the database. When I last updated Mongoose this part broke. And to be honest I do not like this dependency. Things should be kept simple and more easily testable.
I know I have my self signed up for the Mongoose Schema task in TsED but right now I still need a more clear view of how data is to flow from one boundary to the next.
Does this makes sense? Any thoughts?
KR
Lasse
Hi @lwallent.
I agree with you. There are DTO model in nestJS that can use on Controller, Service to represent data. Ts.ED can benchmark it.
https://docs.nestjs.com/techniques/mongodb
https://github.com/nestjs/nest/tree/master/examples/14-mongoose-module
@bjkimFlitto Ts.ED has the same things
Except with the readonly keyword (I'm not sure if it work fine with Ts.ED), I can write the same example:
import { Controller, Get, Post, BodyParams, PathParams } from 'ts-express-decorators';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Post()
async create(@BodyParams() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
The model:
import {Property} from "ts-express-decorators";
export class CreateCatDto {
@Property()
readonly name: string;
@Property()
readonly age: number;
@Property()
readonly breed: string;
}
In the service, actually inject a mongoose schema is not supported. It's very interesting to provide the same feature.
import * as Mongoose from 'mongoose';
import { Service } from 'ts-express-decorators';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatSchema } from './schemas/cat.schema';
const catModel = new Mongoose.model(CatSchema)
@Service()
export class CatsService {
constructor() {}
async create(createCatDto: CreateCatDto): Promise<Cat> {
const createdCat = new catModel(createCatDto);
return await createdCat.save();
}
async findAll(): Promise<Cat[]> {
return await catModel.find().exec();
}
}
So, are you agree with this example ?
See you,
Romain
Readonly keyword work fine :)
Thank you @Romakita !! I think it is very good example and should add in docs.
I just wonder is there is any plan to combine model schema and DTO?
like below
import {Entity, Column} from "ts-express-decorators";
@Entity()
export class Cat {
@Column("text")
description: string;
isValidCat() {
// custom logic for cat dto.
}
}
@Service()
export class CatsService {
constructor(@inject(Cat) private Cat: Cat) {}
async create(catData: Cat): Promise<Cat> {
if (!Cat.isValidCat(catData)) return Promise.reject('no valid cat')
const createdCat = new catModel(createCatDto);
return await createdCat.save();
}
}
the example is affected by https://github.com/typeorm/typeorm
The reason is that it could be very annoying task to make schema and DTO.
Both have almost same data. Only difference is schema is used for database and dto is for custom logics.
sequelize provides methods to handle data but that is not enough.
See you,
jindev
Hi @jindev
I am sure what you mean by agreeing with me, as I was promoting the use of plain objects!?
:-)
KR
Lasse
@jindev Yes, a new section on the Model in the documentation is necessary :). Because this example is already explained in the documentation in different cases.
Hi @Romakita
The problem in your example is when passing the TsED Model to the Mongoose Model as it will expect a plain javascript object. If we pass in a rich TsED model you have to hack the internals of the mongoose serialization and that has proven challenging in my case.
async create(createCatDto: CreateCatDto): Promise<Cat> {
const createdCat = new catModel(createCatDto); // <<<< should be a plain javascript object
Please note I am not criticising TsED or talking in favour of anything else :-)
I am really trying to discuss prober boundaries of the framework. Like where does the life of the TsED model end or how will it work seamlessly with the surroundings?
One way to fix the above example was by introducing the before mentioned toObject
async create(createCatDto: CreateCatDto): Promise<Cat> {
const createdCat = new catModel(createCatDto.toObject()); // <<<< Now it would work
Only problem is that you will then have to remember to call toObject everywhere
In order to get around this you can take different approaches:
_option 1_: you can make TsED model inherit from Mongoose Model. I personally do not like this approach as it makes things really messy.
_option 2_: you can take over the serialisation of Mongoose. I personally do not like this, as it has proven error prone and difficult to test and maintain.
_option 3_: you clearly define the boundaries of the TsED model and add the possibility to have the toObject called behind the scenes. This was what I was trying to describe in my previous post. I like this approach as it separates concerns, is easily testable and clearly defines boundaries.
Please note: option 3 does not mean that TsED cannot be used to assist with the Mongoose implementation. It is just in a more clean-cut way where you take your TsED Model and produce a Mongoose Schema definition (TsED does not interfere with the internals of Mongoose):
[TsED Model] > [Mongoose SchemaDefinition] > [Mongoose Schema] > [Mongoose Model]
KR
Lasse
@lwallent yes, I think dto should be plain obj when create instance of model with it.
Or it would be great if model does't care about data is plain obj or not. ( if Ts.ED can convert data to plain obj when create model instance. 😄 ).
@lwallent Nestjs use a class as DTO. I think Nestjs with the InjectModel decorator find a way to use Mongoose with a class. I'll explore this solution and your solution too ;)
@Romakita sounds great.
... or maybe Nestjs have not tried nested complex objects (classes with class properties).
The Cat example would also work with TsED! :-)
KR
Lasse
Hi guys,
I want to share with you my work on the moving package under npm organization. You can see the new Organization here https://www.npmjs.com/org/tsed
To do that I've create a new branch with a new folder architecture (not a big change) https://github.com/Romakita/ts-express-decorators/tree/feat_multi_package
If you want to become a member, send me a message ;)
This step it's necessary. The project growth and maintain all modules isn't not easy. Now with this new architecture, create a new package is more easy :).
Tell me what you think !
Next step is create a new mongoose package :p and add documentation "how to create a package (plugin) for Ts.ED".
See you,
Romain
Hello Romain,
That's a great innovation!
I would like to be a member.
Thanks in advance.
ing. Anicet Foba Togue
Twitter: @atogue
2018-02-14 8:11 GMT+01:00 Romain Lenzotti notifications@github.com:
Hi guys,
I want to share with you my work on the moving package under npm
organization. You can see the new Organization here
https://www.npmjs.com/org/tsedTo do that I've create a new branch with a new folder architecture (not a
big change) https://github.com/Romakita/ts-express-decorators/tree/
feat_multi_packageIf you want to become a member, send me a message ;)
This step it's necessary. The project growth and maintain all modules
isn't not easy. Now with this new architecture, create a new package is
more easy :).Tell me what you think !
Next step is create a new mongoose package :p and add documentation "how
to create a package (plugin) for Ts.ED".See you,
Romain—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Romakita/ts-express-decorators/issues/230#issuecomment-365516002,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFYXxit-zBOwk4E8zDy_RoUW9ie8nVuiks5tUoc4gaJpZM4R2okY
.
Hi @atogue
I need to have your login on npm ;)
See you "grand manitou" :p
Hi @Romakita
I like the way you have split up things.
Maybe one could have included common within core as top many parts can also be hard to maintain - just a thought.
You may add me (same login) - hopefully I will get more time some day to contribute some more ;-)
Keep up the great work!
Kr Lasse
Hi @lwallent
I want to use @tsed/core as a part of other projects. And it's very small. The advantage in the code, you can import more easily a function from @tsed/core to other Ts.ED package. For the developer it change nothing.
This change is compatible with the old ts-express-decorators npm module.
ts-express-decorators call directly the new package @tsed/core and @tsed/common.
I've added you account to the developer team ;). Now you can publish package under @tsed namespace :p
See you,
Romain
@lwallent
I've added a task to auto install the package in the development. Just run a npm install and all packages will be mounted in your node_modules with an npm link. Easy to use ;) I think you'll like that !
Romain
Hello maestro :-)
my mpn login is: anicet
Thanks in advance ;)
ing. Anicet Foba Togue
Twitter: @atogue
2018-02-15 8:06 GMT+01:00 Romain Lenzotti notifications@github.com:
Hi @atogue https://github.com/atogue
I need to have your login on npm ;)See you "grand manitou" :p
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Romakita/ts-express-decorators/issues/230#issuecomment-365842277,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFYXxg0Mg_QcARUnnouLv9Z0wxCnt_xZks5tU9dtgaJpZM4R2okY
.
hi, @Romakita
I would like to be a member!
thank you
@atogue @jindev It's done :)
Hi all,
I've added Ts.ED on the opencollective website :) https://opencollective.com/tsed
Same question. Who want to have a account on this website ? I need your mail :)
Hi all,
Great news, I've found a solution to use mongoose and Ts.ED without a problem with a class.
schema.loadClass(MyClassModel)
This method introduce with mongoose v4.7 works really fine. Actually, I work on the feature mongoose in Ts.ED. I'm in the testing phase.
See https://github.com/Romakita/ts-express-decorators/tree/feat_mongoose
@mitevs work on the Interceptor feature. His work is in progress :D
See you
Romain
Hi,
I was wondering if you are considering adding HATEOAS to the framework in the future.
It seems like it pops up in many "REST API best practices" articles online, and it does help working with REST APIs
Thanks! 😄
@Romakita why was this closed?
is there a new roadmap?
The backlog here is the roadmap . A large part of the features describe in this issue are implemented. This is why I closed this issue :)
Most helpful comment
Hi @jindev,
Thanks for this project example. Nestjs is awesome :D
To answer you, Ts.ED has the same approach. I've look on Angular to build this framework (like DI, Controller, etc...). Ts.ED is decorator oriented, Nestjs provides less (maybe is a better approach XD).
Features comparison:
Core features | Ts.ED | Nestjs
---|---|---
Lifecycle | yes | no
Module | no | yes
Controllers | yes | yes
Services | yes | yes
Factory |Â yes | yes but not found example
Middlewares | yes | yes
HttpExceptions | yes | yes
Converters | yes | No
Model | yes | yes
Pipe | yes | yes
Auth | yes | yes
Guard | no | yes
JsonSchema | yes | no
Custom decorator | yes | yes
Interceptor | no | yes
Extra features | Ts.ED | Nestjs
---|---|---
Validation | yes | no
Swagger | yes | no
Socket | yes | yes
GraphQL | no | yes
I've in mind some feature for the future of Ts.ED:
@tsednpm scope. (Example:@tsed/core,@tsed/di,@tsed/core,@tsed/ajv, etc...).All of this need a time to work on and any help are welcome ;)
I hope this answer help you to see the Ts.ED future and the difference between Ts.ED and Nestjs (or not).
See you,
Romain