Open petyunchik opened 4 years ago
@petyunchik I'm not sure I understand the comment. You can use it if you inject the assembler.
@doug-martin Sorry, I mean that AssemblerQueryService
is not calling Assembler's convertAsyncToEntity
method anywhere. Even if some async logic will be added to convertAsyncToEntity
it wouldn't be executed by default AssemblerQueryService
.
By default, the auto-generated resolver executes convertToDto
, if you need to handle async operations on the assembler we need to override the resolver in order to call the convertAsyncToDto
which is a bit redundant in my perspective. Why not always call convertAsyncToDto
?
This is not ideal, now I have 2 services (MongooseQueryService, AssemblerQueryService), 1 assembler, and 1 custom resolver just to convert a string to another string with an async operation?!
My code:
export class CompaniesService extends AssemblerQueryService<CompanyDTO, Company> {
constructor(
readonly assembler: CompaniesAssembler,
@Inject(CompaniesQueryService) readonly service: CompaniesQueryService,
) {
super(assembler, service);
}
async findById(id: string): Promise<CompanyDTO> {
const company = await this.service.findById(id)
return this.assembler.convertAsyncToDTO(Promise.resolve(company))
}
}
@Assembler(CompanyDTO, Company)
export class CompaniesAssembler extends ClassTransformerAssembler<CompanyDTO, Company> {
constructor(
@Inject(S3Service) private readonly s3: S3Service
) {
super();
}
async convertAsyncToDTO(entity: Promise<Company>): Promise<CompanyDTO> {
console.log('here???')
const company = await entity
const dto = super.convertToDTO(company)
if (company.logo) {
dto.logo = await this.s3.getObjectSignedUrl(company?.logo)
}
return dto
}
async convertAsyncToDTOs(entities: Promise<Company[]>): Promise<CompanyDTO[]> {
const companies = await entities
const dtos = await Promise.all(
companies.map(async company => this.convertAsyncToDTO(Promise.resolve(company)))
)
return dtos
}
}
import { Inject } from '@nestjs/common';
import { Resolver, Query, Args, ArgsType, ObjectType, Mutation, Field, InputType, ResolveField, Parent, ID } from '@nestjs/graphql';
import { CheckPolicies } from '../casl/check-policies.decorator';
import { CompaniesQueryService } from './companies.queryService';
import { CompaniesService } from './companies.service';
import { CompanyDTO } from './dto/company.dto';
@Resolver(() => CompanyDTO)
export class CompanyResolver {
constructor(
@Inject(CompaniesQueryService) private readonly queryService: CompaniesQueryService,
@Inject(CompaniesService) private readonly service: CompaniesService
) {}
@Query(() => CompanyDTO)
async company(@Args('id', { type: () => ID }) id: string): Promise<CompanyDTO> {
return this.service.findById(id)
}
}
const modules = [
NestjsQueryGraphQLModule.forFeature({
assemblers: [CompaniesAssembler],
imports: [
NestjsQueryMongooseModule.forFeature([
{ document: Company, name: Company.name, schema: CompanySchema },
]),
],
services: [CompaniesService, CompaniesQueryService],
resolvers: [
{
ServiceClass: CompaniesService,
AssemblerClass: CompaniesAssembler,
DTOClass: CompanyDTO,
EntityClass: Company,
CreateDTOClass: CompanyInputDTO,
create: { decorators: [CheckPolicies(CreateCompanyPolicyHandler)] },
read: { decorators: [CheckPolicies(ReadCompanyPolicyHandler)] },
update: { decorators: [CheckPolicies(UpdateCompanyPolicyHandler)] },
delete: { decorators: [CheckPolicies(DeleteCompanyPolicyHandler)] },
pagingStrategy: PagingStrategies.OFFSET
}
],
}),
]
@Module({
providers: [CompanyResolver],
imports: modules,
exports: modules
})
export class CompaniesModule { }
@doug-martin
Same issue like @Fatxx described, I just need to create s3 signed url :(
@Fatxx How did you managed DI to work in Assembler? Looks like it's impossible, since the class creates by the custom factory https://github.com/doug-martin/nestjs-query/blob/master/packages/core/src/assemblers/assembler.factory.ts
There is
convertAsyncToEntity
method declared in Assembler class, but it's not in use anywhere. Would be very useful to make it work similar way asconvertAsyncToDTO
to perform async transformations.And thank you for the library!