如何使用GraphQL架构进行类似JSON Schema的数据验证?

Ben*_*oyt 19 python validation json jsonschema graphql

我们正在研究将GraphQL用于我们正在开发的无头CMS的第2版.

在这个CMS的第1版中,我们使用JSON Schema在保存到数据库之前根据模式验证每个文档 - 例如,如果它是博客文章,它将根据Article模式进行验证,如果它是一个综合("最好的"列表"它将根据Roundup架构进行验证.

对于版本2,我们正在考虑将GraphQL用于API.然后我们发现GraphQL模式基本上与JSON模式并行 - 它描述了文档结构,字段类型等.

因此,我们可以简单地使用"一个模式真实来源",即GraphQL模式,并在保存新版本时使用它来查询文档和验证新文档.(请注意,我正在讨论针对GraphQL架构验证JSON数据,而不是针对架构验证GraphQL查询.)

我认为数据将针对架构中的所有字段进行验证,但已弃用的字段除外,因为您只想验证字段的"最新版本".

我们可以做以下三件事之一:

  1. 直接使用GraphQL AST来验证文档,即自己编写数据验证器.
  2. 使用GraphQL AST生成JSON模式,并使用标准JSON模式验证器来实际验证它.
  3. 只是接受GraphQL不太适合验证,并定义模式两次 - 一次在GraphQL中进行查询,再次在JSON Schema中进行验证(烦人且容易出错以保持同步).

问题:#1和#2愚蠢的想法?是否有任何GraphQL工具可以进行这种数据验证?如果没有定义两次架构,还有其他方法可以实现吗?

作为参考,我们的后端将用Python编写,但管理UI将是客户端的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
}
Run Code Online (Sandbox Code Playgroud)

Ed.*_*Ed. 2

不断变化的形势的确定性程度

GraphQL 仍然是一项不断发展的技术(正如它在规范文档顶部所说的那样),因此可以肯定地说,对此没有真正的“正确”答案。

一般性

InputObject 类型(接口定义语言术语中的“输入”)与列表(IDL 术语中的“[]”)以及各种标量似乎完全涵盖了您可以在 JSON 中执行的操作。

如果 GraphQL 的 Python 实现符合规范,那么以 GraphQL 文字或(更好)作为“变量”提供数据应该提供自定义验证可以提供的一切:GraphQL 验证将做正确的事情。

针对您的情况提出建议

根据我迄今为止使用 GraphQL 的工作,我的建议是“顺其自然”。如果您的 GraphQL 架构符合您的数据架构要求,则只需使用普通的 GraphQL 验证即可。如果您确实进行自己的验证,则应该在GraphQL 完成正常的数据形状检查之后进行。

总结以上几点,并用一个问题来回答您的问题:让 GraphQL 正常运行来完成验证繁重工作有什么问题吗?