Я создаю API GraphQL , используя NestJS и TypeORM. Начиная с классической сущности пользователя, я создал как user.type.ts
, так и user.entity.ts
, как описано в документации Nestjs.
Это пример содержания:
user.entity.ts
@Entity({ schema: 'mydb', name: 'userList' })
export class User {
@Column('varchar', { name: 'guid', unique: true, length: 36 })
guid: string;
@Column('varchar', { name: 'firstName', length: 50 })
firstName: string;
@Column('varchar', { name: 'lastName', length: 100 })
lastName: string;
// ...
user.type.ts
@ObjectType()
export class UserType {
@Field({
name: 'ID',
description: 'Global Universal ID of the User',
})
guid: string;
@Field()
firstName: string;
@Field()
lastName: string;
// ...
Вопрос: поскольку они используют одни и те же поля, могу ли я создать единый класс, объединяющий декораторы обоих классов?
Например:
@Entity({ schema: 'mydb', name: 'userList' })
@ObjectType()
export class User {
@Column('varchar', { name: 'guid', unique: true, length: 36 })
@Field({
name: 'ID',
description: 'Global Universal ID of the User',
})
guid: string;
@Field()
@Column('varchar', { name: 'firstName', length: 50 })
firstName: string;
@Field()
@Column('varchar', { name: 'lastName', length: 100 })
lastName: string;
Это антипаттерн? Есть ли какие-либо ограничения или недостатки в этом?
заранее спасибо
Вы можете сделать то, что предлагаете. Это не проблема. И это личное предпочтение.
Однако вы, вероятно, быстро поймете, как и я, что, несмотря на то, что они имеют одинаковую форму с точки зрения структуры данных, сущность и объект GraphQL (или, в терминах NestJS, объект передачи данных или DTO) имеют разные цели. Вы также обнаружите, что в некоторых ситуациях необходимо преобразовать одно в другое, и для этого потребуется, чтобы они были отдельными.
Я использовал DTO с REST, но в graphql я думаю, что они бесполезны, поскольку сопоставление полей и проверки выполняются graphql. Более того, для аргументов запросов/мутаций я использую отдельный класс. Смешанный класс, о котором я говорил выше, будет использоваться только для полезной нагрузки gql, и я могу легко скрывать/преобразовывать/расширять поля с помощью декораторов graphl. Пока не вижу смысла их разделять. Не могли бы вы привести пример из реальной жизни?
@Joseph - Один отличный пример, который я могу назвать, - это когда имя поля вашего API должно отличаться от имени поля вашей базы данных. Если вы создаете сущность и объект GraphQL вместе, вы застряли с именем API и именами полей сущности, которые должны быть одинаковыми. Может показаться, что это не проблема, но может быть.
Спасибо! Да, я думал о том же, но на самом деле с помощью декоратора @Field на Nestjs вы можете определить сопоставление имени поля. Например: @Field({name: ID}) guid: string;
это означает, что ваше поле базы данных называется guid, но оно отображается как идентификатор. Также вы можете использовать @HideField и тому подобное. Пока не вижу ограничений, но тоже постараюсь их заметить
У меня есть случай, когда объекты не соответствуют точно объектам. У меня есть заказы с продуктами, но я сохраняю только productId и разрешаю данные о продукте из другой системы.
Здесь я думаю, что имеет смысл разделить их для безопасности типов. Я не получаю реальный объект product {}, только productId, но typescript думает, что у меня есть оба.
Привет! Спасибо за ответ!