AbsintheGraphQLSchema设计Skill absinthe-schema

Absinthe是一个用于Elixir语言中设计GraphQL schema的工具,帮助开发者构建高效、可维护的API。它涵盖类型定义、接口、联合、枚举和schema组织模式,优化后端数据查询和变更。关键词:GraphQL, Elixir, schema设计, 类型定义, 接口, 枚举, 后端开发。

后端开发 0 次安装 0 次浏览 更新于 3/25/2026

名称: absinthe-schema 用户可调用: false 描述: 在使用Absinthe设计GraphQL schema时使用。涵盖类型定义、接口、联合、枚举和schema组织模式。

Absinthe - Schema设计

在Elixir中使用Absinthe设计GraphQL schema的全面指南。

关键概念

类型定义

defmodule MyApp.Schema.Types do
  use Absinthe.Schema.Notation

  object :user do
    field :id, non_null(:id)
    field :name, non_null(:string)
    field :email, :string
    field :posts, list_of(:post) do
      resolve &MyApp.Resolvers.User.posts/3
    end
    field :inserted_at, :datetime
  end

  object :post do
    field :id, non_null(:id)
    field :title, non_null(:string)
    field :body, :string
    field :author, :user do
      resolve &MyApp.Resolvers.Post.author/3
    end
  end
end

接口

interface :node do
  field :id, non_null(:id)

  resolve_type fn
    %MyApp.User{}, _ -> :user
    %MyApp.Post{}, _ -> :post
    _, _ -> nil
  end
end

object :user do
  interface :node
  field :id, non_null(:id)
  field :name, non_null(:string)
end

联合

union :search_result do
  types [:user, :post, :comment]

  resolve_type fn
    %MyApp.User{}, _ -> :user
    %MyApp.Post{}, _ -> :post
    %MyApp.Comment{}, _ -> :comment
    _, _ -> nil
  end
end

枚举

enum :post_status do
  value :draft, as: "draft"
  value :published, as: "published"
  value :archived, as: "archived"
end

输入对象

input_object :create_post_input do
  field :title, non_null(:string)
  field :body, :string
  field :status, :post_status, default_value: :draft
end

最佳实践

  1. 按域组织类型 - 将相关类型分组到单独的模块中
  2. 谨慎使用non_null - 仅用于真正必需的字段
  3. 利用接口 - 用于跨类型的共享字段
  4. 定义输入对象 - 用于复杂的变更参数
  5. 使用自定义标量 - 用于日期、UUID、JSON等

Schema组织

defmodule MyApp.Schema do
  use Absinthe.Schema

  import_types MyApp.Schema.Types
  import_types MyApp.Schema.Queries
  import_types MyApp.Schema.Mutations
  import_types MyApp.Schema.Subscriptions
  import_types Absinthe.Type.Custom  # DateTime, etc.

  query do
    import_fields :user_queries
    import_fields :post_queries
  end

  mutation do
    import_fields :user_mutations
    import_fields :post_mutations
  end

  subscription do
    import_fields :post_subscriptions
  end
end

自定义标量

scalar :uuid, name: "UUID" do
  serialize &to_string/1
  parse &parse_uuid/1
end

defp parse_uuid(%Absinthe.Blueprint.Input.String{value: value}) do
  case Ecto.UUID.cast(value) do
    {:ok, uuid} -> {:ok, uuid}
    :error -> :error
  end
end

defp parse_uuid(_), do: :error

反模式

  • 避免没有分页的深度嵌套类型
  • 不要直接暴露数据库ID而不加考虑
  • 避免类型定义中的循环依赖
  • 不要跳过字段描述以用于文档