Русский
Русский
English
Статистика
Реклама

GraphQL Typescript любовь. TypeGraphQL v1.0



ЗTypeGraphQL v1.0


19 августа вышел в релиз фреймворк TypeGraphQL, упрощающий работу с GraphQL на Typescript. За два с половиной года проект обзавёлся солидным комьюнити и поддержкой нескольких компаний и уверено набирает популярность. Спустя более 650 коммитов у него более 5000 звёзд и 400 форков на гитхабе, плод упорной работы польского разработчика Михала Литека. В версии 1.0 значительно улучшилась производительность, схемы получили изоляцию и избавились от прежней избыточности, появились две крупные фичи директивы и расширения, фреймворк был приведён к полной совместимости с GraphQL.

Для чего этот фреймворк?


Михал, ссылаясь на свой опыт работы с голым GraphQL, называет процесс разработки болезненным из-за избыточности и сложности изменения существующего кода:

  1. Сначала нужно создать все необходимые типы GraphQL в формате SDL (Schema Definition Language);
  2. Затем мы создаём модели данных в ORM (Object-Relational Mapping), чтобы описать объекты в базе данных;
  3. После этого надо написать преобразователи для всех запросов, мутаций и полей, что вынуждает нас...
  4. Создавать тайпскриптовые интерфейсы для всех аргументов, инпутов и даже типов объектов.
  5. Только после этого преобразователями можно пользоваться, не забывая при этом вручную проверять рутинные вещи вроде валидации, авторизации и загрузки зависимостей.


Звучит не очень практично, и при таком подходе главная проблема в избыточности кода, которая затрудняет синхронизацию всех параметров при его написании и добавляет рисков при изменениях. Чтобы добавить новое поле к нашей сущности, мы должны перебрать все файлы: изменить класс сущности, затем изменить часть схемы и интерфейс. То же самое и с входными данными или аргументами, легко забыть обновить один элемент или ошибиться в одном типе.

Для борьбы с избыточностью и автоматизации всего этого ручного труда и был создан TypeGraphQL. В его основе лежит идея хранить всю информацию в одном месте, описывая схему данных через классы и декораторы. Ручной труд по внедрению зависимостей, валидации данных и авторизации фреймворк также берёт на себя, разгружая разработчика.

Принцип работы


Разберём работу TypeGraphQL на примере GraphQL API для базы рецептов.

Так будет выглядеть схема в SDL:

    type Recipe {        id: ID!        title: String!        description: String        creationDate: Date!        ingredients: [String!]!    }


Перепишем её в виде класса Recipe:

    class Recipe {        id: string;        title: string;        description?: string;        creationDate: Date;        ingredients: string[];    }


Снабдим класс и свойства декораторами:

    @ObjectType()    class Recipe {        @Field(type => ID)        id: string;        @Field()        title: string;        @Field({ nullable: true })        description?: string;        @Field()        creationDate: Date;        @Field(type => [String])        ingredients: string[];    }


Подробные правила описания полей и типов в соответствующем разделе документации

Затем мы опишем обычные CRUD запросы и мутации. Для этого создадим контроллер RecipeResolver c RecipeService, переданным в конструктор:

    @Resolver(Recipe)    class RecipeResolver {        constructor(private recipeService: RecipeService) {}        @Query(returns => Recipe)        async recipe(@Arg("id") id: string) {            const recipe = await this.recipeService.findById(id);            if (recipe === undefined) {                throw new RecipeNotFoundError(id);            }            return recipe;        }        @Query(returns => [Recipe])        recipes(@Args() { skip, take }: RecipesArgs) {            return this.recipeService.findAll({ skip, take });        }        @Mutation(returns => Recipe)        @Authorized()        addRecipe(            @Arg("newRecipeData") newRecipeData: NewRecipeInput,            @Ctx("user") user: User,        ): Promise<Recipe> {            return this.recipeService.addNew({ data: newRecipeData, user });        }        @Mutation(returns => Boolean)        @Authorized(Roles.Admin)        async removeRecipe(@Arg("id") id: string) {            try {                await this.recipeService.removeById(id);                return true;            } catch {                return false;            }        }    }


Здесь декоратор @Authorized() применяется для ограничения доступа для неавторизованных (или обладающих недостаточными правами) пользователей. Подробнее про авторизацию можно почитать в документации.

Пора добавить NewRecipeInput и RecipesArgs:

@InputType()class NewRecipeInput {@Field()@MaxLength(30)title: string;@Field({ nullable: true })@Length(30, 255)description?: string;@Field(type => [String])@ArrayMaxSize(30)ingredients: string[];}@ArgsType()class RecipesArgs {@Field(type => Int, { nullable: true })@Min(0)skip: number = 0;@Field(type => Int, { nullable: true })@Min(1) @Max(50)take: number = 25;}


Length, Min и @ArrayMaxSize это декораторы из класса-валидатора, которые автоматически выполняют проверку полей.

Последний шаг собственно сборка схемы. Этим занимается функция buildSchema:

    const schema = await buildSchema({        resolvers: [RecipeResolver]    });


И всё! Теперь у нас есть полностью рабочая схема GraphQL. В скомпилированном виде она выглядит так:

type Recipe {id: ID!title: String!description: StringcreationDate: Date!ingredients: [String!]!}input NewRecipeInput {title: String!description: Stringingredients: [String!]!}type Query {recipe(id: ID!): Reciperecipes(skip: Int, take: Int): [Recipe!]!}type Mutation {addRecipe(newRecipeData: NewRecipeInput!): Recipe!removeRecipe(id: ID!): Boolean!}


Это пример базовой функциональности, на самом деле TypeGraphQL умеет использовать ещё кучу инструментов из арсенала TS. Ссылки на документацию вы уже видели :)

Что нового в 1.0


Вкратце пройдёмся по основным изменениям релиза:

Производительность


TypeGraphQL это по сути дополнительный слой абстракции над библиотекой graphql-js, и он всегда будет работать медленнее её. Но теперь, по сравнению с версией 0.17, на выборке из 25000 вложенных объектов фреймфорк добавляет в 30 раз меньше оверхеда с 500% до 17% с возможностью ускорения до 13%. Отдельные нетривиальные способы оптимизации описаны в документации.

Изоляция схем


В старых версиях схема строилась из всех метаданных, получаемых из декораторов. Каждый последующий вызов buildSchema возвращал одну и ту же схему, построенную из всех доступных в хранилище метаданных. Теперь же схемы изолированы и buildSchema выдаёт только те запросы, которые напрямую связаны с заданными параметрами. То есть изменяя лишь параметр resolvers мы поулчаем разные операции над схемами GraphQL.

Директивы и расширения


Это два способа добавить метаданные в элементы схемы: директивы GraphQL являются часть SDL и могут быть объявлены прямо в схеме. Также они могут изменять её и выполнять специфические операции, например, сгенерировать тип соединения для пагинации. Применяются они с помощью декораторов @Directive и @Extensions и различаются подходом к построению схемы. Документация Directives, Документация Extensions.

Преобразователи и аргументы для полей интерфейсов


Последний рубеж полной совместимости с GraphQL лежал здесь. Теперь можно определять преобразователи для полей интерфейса, используя синтаксис @ObjectType:

    @InterfaceType()    abstract class IPerson {        @Field()        avatar(@Arg("size") size: number): string {            return `http://i.pravatar.cc/${size}`;        }    }


Немногочисленные исключения описаны здесь.

Преобразование вложенных инпутов и массивов


В предыдущих версиях экземпляр класса инпута создавался только на первом уровне вложенности. Это создавало проблемы и баги с их валидацией. Fixed.

Заключение


В течение всего времени разработки, проект оставался открытым к идеям и критике, опенсорсным и зажигательным. 99% кода написал сам Михал Литек, но и сообщество внесло огромный вклад в развитие TypeGraphQL. Теперь, с нарастающей популярностью и финансовой поддержкой, он может стать настоящим стандартом в своей области.

Сайт
Гитхаб
Доки
Твиттер Михала

Источник: habr.com
К списку статей
Опубликовано: 26.08.2020 14:06:49
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ruvds.com

Программирование

Typescript

Лайфхаки для гиков

Graphql

Фреймворк

Ruvds_статьи

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru