absinthe-schema

$npx mdskill add TheBushidoCollective/han/absinthe-schema

Design robust GraphQL schemas with Absinthe in Elixir.

  • Define types, interfaces, unions, and enums for complex data models.
  • Integrates with Absinthe library for Elixir GraphQL implementation.
  • Generates schema code using functional notation and resolver patterns.
  • Outputs executable schema definitions ready for API deployment.

SKILL.md

.github/skills/absinthe-schemaView on GitHub ↗
---
name: absinthe-schema
user-invocable: false
description: Use when designing GraphQL schemas with Absinthe. Covers type definitions, interfaces, unions, enums, and schema organization patterns.
---

# Absinthe - Schema Design

Comprehensive guide to designing GraphQL schemas with Absinthe in Elixir.

## Key Concepts

### Type Definitions

```elixir
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
```

### Interfaces

```elixir
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
```

### Unions

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

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

### Enums

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

### Input Objects

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

## Best Practices

1. **Organize types by domain** - Group related types in separate modules
2. **Use non_null sparingly** - Only for truly required fields
3. **Leverage interfaces** - For shared fields across types
4. **Define input objects** - For complex mutation arguments
5. **Use custom scalars** - For dates, UUIDs, JSON, etc.

## Schema Organization

```elixir
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
```

## Custom Scalars

```elixir
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
```

## Anti-Patterns

- Avoid deeply nested types without pagination
- Don't expose database IDs directly without consideration
- Avoid circular dependencies in type definitions
- Don't skip field descriptions for documentation

More from TheBushidoCollective/han

SkillDescription
absinthe-resolversUse when implementing GraphQL resolvers with Absinthe. Covers resolver patterns, dataloader integration, batching, and error handling.
absinthe-subscriptionsUse when implementing real-time GraphQL subscriptions with Absinthe. Covers Phoenix channels, PubSub, and subscription patterns.
act-docker-setupUse when configuring Docker environments for act, selecting runner images, managing container resources, or troubleshooting Docker-related issues with local GitHub Actions testing.
act-local-testingUse when testing GitHub Actions workflows locally with act. Covers act CLI usage, Docker configuration, debugging workflows, and troubleshooting common issues when running workflows on your local machine.
act-workflow-syntaxUse when creating or modifying GitHub Actions workflow files. Provides guidance on workflow syntax, triggers, jobs, steps, and expressions for creating valid GitHub Actions workflows that can be tested locally with act.
ameba-configurationUse when configuring Ameba rules and settings for Crystal projects including .ameba.yml setup, rule management, severity levels, and code quality enforcement.
ameba-custom-rulesUse when creating custom Ameba rules for Crystal code analysis including rule development, AST traversal, issue reporting, and rule testing.
ameba-integrationUse when integrating Ameba into development workflows including CI/CD pipelines, pre-commit hooks, GitHub Actions, and automated code review processes.
analyze-performanceAnalyze performance metrics and identify slow transactions in Sentry
android-jetpack-composeUse when building Android UIs with Jetpack Compose, managing state with remember/mutableStateOf, or implementing declarative UI patterns.