Мы изучаем использование GraphQL для версии 2 безголовой CMS, которую мы разрабатываем.
В версии 1 этой CMS мы использовали схему JSON для проверки каждого документа по схеме перед сохранением в базе данных - например, если это статья в блоге, она будет проверена против схемы Article
и если он округляет ( "лучший из" списка), он будет проверен против схемы Roundup
.
Для версии 2 мы рассматриваем использование GraphQL для API. И затем нам пришло в голову, что схема GraphQL в основном параллельна схеме JSON - она описывает структуру документа, типы полей и т.д.
Таким образом, мы могли бы просто иметь "один источник истины схемы", схему GraphQL, и использовать это как для запроса документов, так и для проверки новых документов при сохранении новой ревизии. (Обратите внимание, что я говорю о проверке данных JSON против схемы GraphQL, а не на проверке запроса GraphQL на схему.)
Я полагаю, что данные будут проверены против всех полей в схеме, за исключением устаревших полей, потому что вы хотите проверить только "последнюю версию" этих полей.
Мы могли бы сделать одну из трех вещей:
- Используйте GraphQL AST непосредственно для проверки документа, то есть для того, чтобы самим написать валидатор данных.
- Используйте GraphQL AST для создания схемы JSON и используйте стандартный валидатор JSON Schema для фактической проверки.
- Просто согласитесь, что GraphQL не совсем подходит для проверки и определяет схему дважды - один раз в GraphQL для запроса и снова в JSON Schema для проверки (раздражает и подвержен ошибкам, чтобы синхронизировать их).
Вопросы: Являются ли идеи №1 и №2 глупыми? Существуют ли инструменты GraphQL, которые выполняют такую проверку данных? Существуют ли другие способы достижения этого, не определяя схему дважды?
Для справки, наш бэкэнд будет написан на Python, но пользовательский интерфейс администратора будет на стороне клиента React и JavaScript. Это сокращенная версия схемы GraphQL, о которой мы говорим (поддерживает типы документов "Article" и "Roundup" ):
schema {
query: Query
}
type Query {
documents: [Document!]!
document(id: Int): Document!
}
interface Document {
id: Int!
title: String!
}
type Article implements Document {
id: Int!
title: String!
featured: Boolean!
sections: [ArticleSection!]!
}
union ArticleSection = TextSection | PhotoSection | VideoSection
type TextSection {
content: String!
heading: String
}
type PhotoSection {
sourceUrl: String!
linkUrl: String
caption: String
content: String
}
type VideoSection {
url: String!
}
type Roundup implements Document {
id: Int!
title: String!
isAward: Boolean!
intro: String
hotels: [RoundupHotel!]!
}
type RoundupHotel {
url: String!
photoUrl: String @deprecated(reason: "photoUrl is deprecated; use photos")
photos: [RoundupPhoto!]!
blurb: String!
title: String
}
type RoundupPhoto {
url: String!
caption: String
}