Crie esquema grafql e resolvedores com o TypeScript, usando classes e decoradores!
https://typegraphql.com
TypeGraphQL torna o desenvolvimento do GraphQL APIs um processo agradável, ou seja, definindo o esquema usando apenas classes e um pouco de magia do decorador.
Portanto, para criar tipos como tipo de objeto ou tipo de entrada, usamos um tipo de classe DTO. Por exemplo, para declarar o tipo Recipe , simplesmente criamos uma classe e anotá -la com decoradores:
@ ObjectType ( )
class Recipe {
@ Field ( type => ID )
id : string ;
@ Field ( )
title : string ;
@ Field ( type => [ Rate ] )
ratings : Rate [ ] ;
@ Field ( { nullable : true } )
averageRating ?: number ;
}E temos a parte correspondente do esquema em SDL:
type Recipe {
id : ID !
title : String !
ratings : [ Rate ! ] !
averageRating : Float
}Em seguida, podemos criar consultas, mutações e resolvedores de campo. Para esse fim, usamos classes do tipo controlador que são chamadas de "resolvedores" por convenção. Também podemos usar recursos incríveis, como injeção de dependência e autores:
@ Resolver ( Recipe )
class RecipeResolver {
// dependency injection
constructor ( private recipeService : RecipeService ) { }
@ Query ( returns => [ Recipe ] )
recipes ( ) {
return this . recipeService . findAll ( ) ;
}
@ Mutation ( )
@ Authorized ( Roles . Admin ) // auth guard
removeRecipe ( @ Arg ( "id" ) id : string ) : boolean {
return this . recipeService . removeById ( id ) ;
}
@ FieldResolver ( )
averageRating ( @ Root ( ) recipe : Recipe ) {
return recipe . ratings . reduce ( ( a , b ) => a + b , 0 ) / recipe . ratings . length ;
}
}E dessa maneira simples, temos essa parte do esquema em SDL:
type Query {
recipes : [ Recipe ! ] !
}
type Mutation {
removeRecipe ( id : String ! ): Boolean !
}Todos sabemos que o GraphQL é ótimo e resolve muitos problemas que temos com as APIs de repouso, como exageramento e sub-busca. Mas o desenvolvimento de uma API do GraphQL no Node.js com o TypeScript é às vezes um pouco de dor. Por que? Vamos dar uma olhada nas etapas que geralmente temos que tomar.
Primeiro, criamos todos os tipos de grafQL no schema.graphql usando SDL. Em seguida, criamos nossos modelos de dados usando classes ORM, que representam nossas entidades de banco de dados. Em seguida, começamos a escrever resolvedores para nossas consultas, mutações e campos, mas isso nos obriga a criar interfaces TS para todos os argumentos, entradas e até tipos de objetos.
Somente então podemos implementar os resolvedores usando assinaturas genéricas estranhas e executando manualmente tarefas comuns, como validação, autorização e carregamento dependências:
export const getRecipesResolver : GraphQLFieldResolver < void , Context , GetRecipesArgs > = async (
_ ,
args ,
ctx ,
) => {
// common tasks repeatable for almost every resolver
const repository = TypeORM . getRepository ( Recipe ) ;
const auth = Container . get ( AuthService ) ;
await joi . validate ( getRecipesSchema , args ) ;
if ( ! auth . check ( ctx . user ) ) {
throw new NotAuthorizedError ( ) ;
}
// our business logic, e.g.:
return repository . find ( { skip : args . offset , take : args . limit } ) ;
} ;O maior problema é a redundância em nossa base de código, o que dificulta manter as coisas em sincronia. Para adicionar um novo campo à nossa entidade, temos que pular todos os arquivos - modificar uma classe de entidade, o esquema, bem como a interface. O mesmo vale para insumos ou argumentos. É fácil esquecer de atualizar uma peça ou cometer um erro com um único tipo. Além disso, e se fizemos um erro de digitação no nome do campo? O recurso de renomeação (F2) não funcionará corretamente.
Tools like GraphQL Code Generator or graphqlgen only solve the first part - they generate the corresponding interfaces (and resolvers skeletons) for our GraphQL schema but they don't fix the schema <--> models redundancy and developer experience (F2 rename won't work, you have to remember about the codegen watch task in the background, etc.), as well as common tasks like validation, authorization, etc.
O TypeGraphQL vem para abordar esses problemas, com base na experiência de alguns anos no desenvolvimento de APIs grafql no TypeScript. A idéia principal é ter apenas uma fonte de verdade, definindo o esquema usando classes e alguma ajuda dos decoradores. Recursos adicionais, como injeção de dependência, validação e guardas de autenticação, ajudam com tarefas comuns que normalmente teríamos que lidar com nós mesmos.
A documentação, o guia de instalação e a descrição detalhada da API e todos os seus recursos estão disponíveis no site.
Um guia de início completo com um simples passo a passo (tutorial) pode ser encontrado no início dos documentos.
Se você preferir tutoriais em vídeo, pode assistir à série de vídeo TypeGraphql de Ben Awad no YouTube.
Você também pode verificar a pasta Exemplos neste repositório para obter mais exemplos de uso: resolvedores simples dos campos, suporte a contêiner DI, integração do Typeorm, validação automática, etc.
A pasta de testes também pode fornecer algumas dicas sobre como fazer várias coisas.
Para relatar uma vulnerabilidade de segurança, use o contato de segurança Tidelift. O Tidelift coordenará a correção e a divulgação.
A versão atualmente lançada é uma versão estável 1.0.0. É bem testado (97% de cobertura, ~ 500 casos de teste) e tem a maioria dos recursos planejados já implementados. Muitas empresas e desenvolvedores independentes estão usando -o em produção com sucesso.
No entanto, também existem planos para muito mais recursos, como integração melhor Typeorm, Prisma e Dataloader, decoradores personalizados e suporte de anotações de metadados - a lista completa de idéias está disponível no repositório do GitHub. Você também pode acompanhar o progresso do desenvolvimento no conselho do projeto.
Se você tiver alguma solicitação de recurso interessante, sinta -se à vontade para abrir um problema no Github para que possamos discutir isso!
TypeGraphQL é um projeto de código aberto licenciado pelo MIT. Essa estrutura é resultado da tremenda quantidade de trabalho - noites sem dormir, noites ocupadas e fins de semana.
Ele não tem uma grande empresa que fica por trás dela - seu desenvolvimento contínuo é possível apenas graças ao apoio da comunidade.
Peça à sua empresa que apoie este projeto de código aberto, tornando -se um patrocinador de ouro e obtendo um suporte técnico premium de nossos principais colaboradores.