{"id":30804243,"url":"https://github.com/rockneurotiko/graphql_query","last_synced_at":"2026-02-17T17:03:07.402Z","repository":{"id":309382690,"uuid":"1036052562","full_name":"rockneurotiko/graphql_query","owner":"rockneurotiko","description":"Elixir library for validating, parsing, and formatting GraphQL queries and schemas","archived":false,"fork":false,"pushed_at":"2025-11-13T16:31:13.000Z","size":2229,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-10T02:08:35.811Z","etag":null,"topics":["elixir","graphql"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rockneurotiko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-11T13:41:58.000Z","updated_at":"2025-12-22T08:25:52.000Z","dependencies_parsed_at":"2025-08-11T16:20:25.992Z","dependency_job_id":"9b990f92-e872-447f-b886-13ae020eb421","html_url":"https://github.com/rockneurotiko/graphql_query","commit_stats":null,"previous_names":["rockneurotiko/graphql_query"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/rockneurotiko/graphql_query","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockneurotiko%2Fgraphql_query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockneurotiko%2Fgraphql_query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockneurotiko%2Fgraphql_query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockneurotiko%2Fgraphql_query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rockneurotiko","download_url":"https://codeload.github.com/rockneurotiko/graphql_query/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockneurotiko%2Fgraphql_query/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29550835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T14:33:00.708Z","status":"ssl_error","status_checked_at":"2026-02-17T14:32:58.657Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","graphql"],"created_at":"2025-09-05T23:57:58.160Z","updated_at":"2026-02-17T17:03:07.396Z","avatar_url":"https://github.com/rockneurotiko.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003e\u003cp align=\"center\"\u003e\u003cimg src=\"graphql_query.png\" alt=\"GraphQL Query\" width=\"350\"\u003e\u003c/p\u003e\u003c/h1\u003e\n\n![CI](https://github.com/rockneurotiko/graphql_query/actions/workflows/ci.yml/badge.svg)\n[![Package](https://img.shields.io/hexpm/v/graphql_query.svg)](https://hex.pm/packages/graphql_query)\n[![Documentation](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/graphql_query)\n\n\u003c!-- MDOC --\u003e\n\nGraphQL Query provides a library for **validating, parsing, and formatting GraphQL queries and schemas**\n\n⚠️ **Disclaimer:** This library is still in early development. APIs may change as it evolves.\n\n---\n\n## Table of Contents\n\n- [Why This Library?](#why-this-library)\n- [Features](#features)\n- [Quick Start](#quick-start)\n  - [Installation](#installation)\n  - [Examples](#examples)\n- [Usage](#usage)\n  - [~GQL Sigil](#gql-sigil)\n  - [gql_from_file Macro](#gql_from_file-macro)\n  - [gql Macro](#gql-macro)\n  - [document_with_options Macro](#document_with_options-macro)\n- [Use the documents in HTTP Requests](#use-the-documents-in-http-requests)\n- [Fragment support](#fragment-support)\n  - [Define fragments](#define-fragments)\n  - [Use fragments](#use-fragments)\n- [Schema Support](#schema-support)\n  - [Parsing and Validating Schemas](#parsing-and-validating-schemas)\n  - [Schema Modules](#schema-modules)\n  - [Document Validation Against Schema](#document-validation-against-schema)\n- [Apollo Federation Support](#apollo-federation-support)\n- [Formatter Integration](#formatter-integration)\n- [Manual API](#manual-api)\n- [Roadmap](#roadmap)\n- [License](#license)\n- [Links](#links)\n\n---\n\n## Why This Library?\n\n- **Developer tool**: Focused on **validation, formatting, compile-time and runtime safety**.\n- **External APIs integration**: Build and validate queries against external GraphQL APIs. Never miss a deprecated field, a type error in the arguments or a typo in the fields you are fetching.\n- **Best match for your tests**: Use in your tests to build and validate queries against any GraphQL schema (external APIs, you own Absinthe schema, ...), catch issues early on development.\n- **Not a GraphQL server**: [Absinthe](https://hex.pm/packages/absinthe) is for building GraphQL servers. `GraphqlQuery` is for validating and formatting queries against schemas (including external APIs). They complement each other perfectly - you can extract your Absinthe schema and use it to validate client queries on tests.\n\n---\n\n## Features\n\n- ✅ **GraphQL queries and mutations validation** (syntax, unused vars, fragments, spec compliance)\n- ✅ **Schema parsing and validation** (from strings or files)\n- ✅ **Fragment support** with composition, reusability, and validation\n- ✅ **Schema-aware query, mutation and fragments validation** (detect invalid fields/types)\n- ✅ **Compile-time macros**:\n  - `~GQL` sigil for static queries\n  - `gql_from_file` for file-based queries\n  - `gql` macro for dynamic queries\n  - `document_with_options` for applying options to multiple macros\n- ✅ **Query formatting** with consistent indentation and automatic formatting option\n- ✅ **Mix format integration** for `~GQL` sigil, `.graphql` and `.gql` files\n- ✅ **Schema modules** with automatic recompilation on schema changes\n- ✅ **Absinthe schema integration** for validating queries against existing Absinthe schemas\n- ✅ **Apollo Federation v2 support** for validating federated schemas with `@key`, `@shareable`, etc.\n- ✅ **Flexible validation modes**: compile-time, runtime, or ignore\n- ✅ **JSON encoding support** for Document structs (JSON/Jason protocols)\n- ⚡ Backed by Rust for fast parsing and validation\n\n---\n\n## Quick Start\n\n### Installation\n\nAdd `graphql_query` to your dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:graphql_query, \"~\u003e 0.4\"}\n  ]\nend\n```\n\nFetch deps:\n\n```bash\nmix deps.get\n```\n\nNo Rust installation required — precompiled binaries are used.\n\n### Examples\n\nYou can find more examples in the [Cheatsheet](cheatsheet.cheatmd), here is a little compilation.\n\n#### Example: Compile-time Document Validation\n\n```elixir\nimport GraphqlQuery\n\n# Valid query\n~GQL\"\"\"\nquery GetUser($id: ID!) {\n  user(id: $id) {\n    name\n  }\n}\n\"\"\"\n\n# Invalid query → compile-time warning\n~GQL\"\"\"\nquery GetUser($unused: String!) {\n  user {\n    name\n  }\n}\n\"\"\"\n# warning: GraphQL validation errors:\n# Error: unused variable: `$unused` at file.ex:10:1 - variable is never used\n```\n\n#### Example: Schema Validation\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema, schema_path: \"priv/graphql/schema.graphql\"\nend\n\ndefmodule MyApp.Queries do\n  use GraphqlQuery, schema: MyApp.Schema\n\n  def get_user_query do\n    ~GQL\"\"\"\n    query GetUser($id: ID!) {\n      user(id: $id) {\n        id\n        name\n        email\n      }\n    }\n    \"\"\"\n  end\nend\n```\n\n#### Example: Usage in requests\n\n```elixir\nquery = gql [fragments: [@user_fragment]], \"\"\"\nquery { ... }\n\"\"\"\n\nuser = \"1\"\nuser_query = GraphqlQuery.Document.add_variable(query, :id, user)\nReq.post!(\"/api\", json: user_query)\n```\n\n---\n\n## Usage\n\n### `~GQL` Sigil\n- For **static queries only** (no interpolation).\n- Validates at compile time.\n- [Optional formatter plugin](#formatter-integration).\n- Supports modifiers, the modifiers are applied at the end of the string: `~GQL\"\"rf`:\n  - `i` → Ignore warnings\n  - `r` -\u003e Validate on runtime\n  - `s` → Parse as schema\n  - `q` → Parse as query (this is the default behaviour)\n  - `f` → Parse as fragment\n  - `F` → Enable Apollo Federation v2 directives (for schemas)\n\n```elixir\nimport GraphqlQuery\n\n# Valid query\n~GQL\"\"\"\nquery GetUser($id: ID!) {\n  user(id: $id) {\n    name\n  }\n}\n\"\"\"\n\n# Ignore warnings\n~GQL\"\"\"\nquery GetUser($id: ID!, $unused: String) {\n  user(id: $id) { name }\n}\n\"\"\"i\n\n# Parse schema\n~GQL\"\"\"\ntype User {\n  id: ID!\n  name: String!\n}\n\"\"\"s\n\n# Parse fragment\n~GQL\"\"\"\nfragment UserData on User {\n  id\n  name\n}\n\"\"\"f\n\n# Delegate validation to runtime\n# Try not to use it, but if you need it you have the option\n~GQL\"\"\"\nquery GetUser($id: ID!) {\n  user(id: $id) {\n    ...UserData\n  }\n}\n\"\"\"r |\u003e GraphqlQuery.Document.add_fragment(user_data)\n\n```\n\n---\n\n### `gql_from_file` Macro\n- Load queries or schemas from `.graphql` or `.gql` files.\n- Validates at compile time.\n- Tracks file changes for recompilation.\n- Options:\n  - `ignore: true` → skip validation\n  - `type: :query | :schema | :fragment` → Specify if the content shall be validated as query, schema or fragment\n  - `schema: SchemaModule` → Specify the schema module to validate the query or fragment with\n  - `fragments: [GraphqlQuery.Fragment.t()]` → Add reusable fragments to queries\n  - `format: true` → Apply automatic formatting when converting to string\n  - `federation: true` → Enable Apollo Federation v2 directive support (for schemas)\n\nExample project structure:\n\n```\npriv/\n├── graphql/\n|   ├── schema.graphql\n|   ├── get_user.graphql\n|   └── create_user.gql\n|   └── user_fragment.gql\n```\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema, schema_path: \"priv/graphql/schema.graphql\"\nend\n\ndefmodule MyApp.Queries do\n  use GraphqlQuery, schema: MyApp.Schema\n\n  @user_fragment gql_from_file \"priv/graphql/user_fragment.gql\", type: :fragment\n\n  def get_user_query do\n    gql_from_file \"priv/graphql/get_user.graphql\", fragments: [@user_fragment]\n  end\n\n  def create_user_mutation do\n    gql_from_file \"priv/graphql/create_user.gql\", schema: MyApp.Schema\n  end\nend\n```\n\n---\n\n### `gql` Macro\n- Supports **dynamic queries** with interpolation.\n- Options:\n  - `evaluate: true` → expand module calls at compile time\n  - `runtime: true` → validate at runtime instead of compile time\n  - `ignore: true` → skip validation\n  - `type: :query | :schema | :fragment` → Specify if the content shall be validated as query, schema or fragment\n  - `schema: SchemaModule` → Specify the schema module to validate the query or fragment with\n  - `fragments: [GraphqlQuery.Fragment.t()]` → Add reusable fragments to queries\n  - `format: true` → Apply automatic formatting when converting to string\n  - `federation: true` → Enable Apollo Federation v2 directive support (for schemas)\n\n```elixir\ndefmodule Example do\n  use GraphqlQuery\n\n  @fields \"name email\"\n\n  # Expand module attributes\n  def query do\n    gql \"\"\"\n    query {\n      user { #{@fields} }\n    }\n    \"\"\"\n  end\n\n  # Expand other module calls\n  def query_with_eval do\n    gql [evaluate: true], \"\"\"\n    query {\n      ...#{OtherModule.fragment_name()}\n      #{OtherModule.more_fields()}\n    }\n    #{OtherModule.fragment()}\n    \"\"\"\n  end\n\n  # Specify fragments for the query\n  def query_with_fragments do\n    gql [fragments: [OtherModule.fragment()]], \"\"\"\n    query {\n      users {\n        ...UserFragment\n      }\n    }\n    \"\"\"\n  end\n\n  # Runtime validation for local variables\n  def query_runtime(user_id) do\n    gql [runtime: true], \"\"\"\n    query {\n      user(id: #{user_id}) { name }\n    }\n    \"\"\"\n  end\n\n  # Automatic formatting when converting to string\n  def formatted_query do\n    gql [format: true], \"\"\"\n    query{user{id name}}\n    \"\"\"\n    # When converted to string, will be properly formatted:\n    # query {\n    #   user {\n    #     id\n    #     name\n    #   }\n    # }\n  end\nend\n```\n\n---\n\n### `document_with_options` Macro\n\n- Apply **common options** to all GraphqlQuery macros and sigils within a block\n- **Key feature**: Enables the `~GQL` sigil to work with complex options like `:schema` and `:fragments`\n- Supports all the same options as individual macros\n- Options are merged with precedence ((explicit macro options | sigil modifiers) \u003e `document_with_options` \u003e module defaults)\n\nThe main use case for the macro `document_with_options` is to  **use fragments and schema validation with sigils**.\nThe `~GQL` sigil doesn't support schema or fragments options directly, but `document_with_options` enables it:\n\n```elixir\n# This won't work - sigils don't support schema options\n~GQL\"\"\"\nquery GetUser { user { id name } }\n\"\"\"[schema: MySchema]  # ❌ Invalid syntax\n\n# This works perfectly\ndocument_with_options schema: MySchema do\n  ~GQL\"\"\"\n  query GetUser { user { ...UserFragment } }\n  \"\"\"  # ✅ Schema validation applied\nend\n```\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema, schema_path: \"priv/schema.graphql\"\nend\n\ndefmodule MyApp.Queries do\n  use GraphqlQuery, schema: MyApp.Schema\n\n  @user_fragment ~GQL\"\"\"\n  fragment UserFragment on User {\n    id\n    name\n  }\n  \"\"\"f\n\n  def user_query do\n    document_with_options fragments: [@user_fragment] do\n      ~GQL\"\"\"\n      query GetUser($id: ID!) {\n        user(id: $id) {\n          ...UserFragment\n        }\n      }\n      \"\"\"\n    end\n  end\nend\n```\n\n---\n\n## Use the documents in HTTP requests\n\nAt the end, we want to build GraphQL queries to do requests to the GraphQL server.\n\nTo make it easy, the GraphQL.Document struct returned by `~GQL`, `gql_from_file` and `gql` implement the protocol for the standard library [`JSON`](https://hexdocs.pm/elixir/JSON.html) and for [`Jason`](https://hexdocs.pm/jason/Jason.html).\n\nTo use queries in requests, you can directly put the query document in the body if the library supports JSON encoding, or manually call `JSON.encode!(query)` or `Jason.encode!(query)` to get the request body as a string.\n\nThe encoding build a json such as `{\"query\": \"document\", \"variables\": {}}`. The document is the query or mutation with the fragments (if any) at the end.\n\nExample with [`Req`](https://github.com/wojtekmach/req) and [`GraphQLZero` mock server](https://graphqlzero.almansi.me):\n\n```elixir\nbase_query = ~GQL\"\"\"\nquery GetUser($id: ID!) {\n  user(id: $id) {\n    id\n    username\n    email\n    address {\n      geo {\n        lat\n        lng\n      }\n    }\n  }\n}\n\"\"\"\n# base_query is a %GraphqlQuery.Document{} struct\n\n# We add variables to create a new document with that information\nuser_query = GraphqlQuery.Document.add_variable(base_query, :id, \"1\")\n\nReq.post!(\"https://graphqlzero.almansi.me/api\", json: user_query).body\n\n# %{\n#   \"data\" =\u003e %{\n#     \"user\" =\u003e %{\n#       \"address\" =\u003e %{\"geo\" =\u003e %{\"lat\" =\u003e -37.3159, \"lng\" =\u003e 81.1496}},\n#       \"email\" =\u003e \"Sincere@april.biz\",\n#       \"id\" =\u003e \"1\",\n#       \"username\" =\u003e \"Bret\"\n#     }\n#   }\n# }\n\n```\n\n---\n\n## Fragment support\n\nYou can define your fragments and use them with the macros.\n\n### Define fragments\n\n```elixir\n# With sigil\nfragment = ~GQL\"\"\"\nfragment UserFragment on User { id name }\n\"\"\"f\n\n# With macro\nfragment = gql [type: :fragment], \"\"\"\nfragment UserFragment on User { id name }\n\"\"\"f\n\n# From file\nfragment = gql_from_file \"fragment.graphql\", type: :fragment\n```\n\n### Use fragments\n\n```elixir\n# With sigils you have to use the global module registration, or manually set them and validate on runtime:\n\ndefmodule UserQuery do\n  use GraphqlQuery, fragments: [MyFragments.user_fragment()], schema: UserSchema\n\n  # Use the fragments registered for the module.\n  def query do\n    ~GQL\"\"\"\n    query GetUser($id: ID!) {\n      user(id: $id) {\n        ...UserFragment\n      }\n    }\n    \"\"\"\n  end\n\n  # Evaluate at runtime, and add the fragments later instead of using the global ones\n  def runtime_query do\n    query = ~GQL\"\"\"\n    query GetUser($id: ID!) {\n      user(id: $id) {\n        ...UserFragment\n      }\n    }\n    \"\"\"r\n\n    GraphqlQuery.Document.add_fragment(query, MyFragments.user_fragment())\n  end\nend\n\n\n# With the gql and gql_from_file macros, you can use the module fragments, or per-query fragments:\n\ngql [fragments: [MyFragments.user_fragment()]], \"\"\"\n    query GetUser($id: ID!) {\n      user(id: $id) {\n        ...UserFragment\n      }\n    }\n\"\"\"\n\ngql_from_file \"query.graphql\", fragments: [MyFragments.user_fragment()]\n```\n\n---\n\n## Schema Support\n\n### Parsing and Validating Schemas\n\nWith macros:\n\n```elixir\nschema = gql [type: :schema], \"\"\"\ntype User { id: ID! name: String! }\ntype Query { user(id: ID!): User }\n\"\"\"\n\nschema = gql_from_file \"path/to/schema.graphql\", type: :schema\n```\n\nOr with sigil:\n\n```elixir\n~GQL\"\"\"\ntype User { id: ID! name: String! }\ntype Query { user(id: ID!): User }\n\"\"\"s\n```\n\n---\n\n### Schema Modules\n- Parses and validates schema at compile time\n- Provides `schema/0` and `schema_path/0`\n- Recompiles when schema file changes\n\n#### From GraphQL Files\n\nAutomatically implement the behaviour with a schema file:\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema, schema_path: \"priv/graphql/schema.graphql\"\nend\n```\n\n#### From Absinthe Schemas\n\nAutomatically extract schema from existing Absinthe schema modules, really useful specially for testing:\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema, absinthe_schema: MyAppWeb.Graphql.Schema\nend\n```\n\n#### Manual Implementation\n\nOr manually implement the behaviour:\n\n```elixir\ndefmodule MyApp.Schema do\n  use GraphqlQuery.Schema\n\n  @impl GraphqlQuery.Schema\n  def schema do\n    ~GQL\"\"\"\n    type User { id: ID! name: String! }\n    type Query { user(id: ID!): User }\n    \"\"\"s\n  end\n\n  @impl GraphqlQuery.Schema\n  def schema_path, do: nil\nend\n```\n\n---\n\n### Document Validation Against Schema\n\nYou can validate against the schema any document (queries, mutations or  fragments)\n\n**Per-document validation:**\n\n```elixir\ngql [schema: MyApp.Schema], \"\"\"\nquery GetUser($id: ID!) {\n  user(id: $id) { name email }\n}\n\"\"\"\n\ngql_from_file \"path.graphql\", [schema: MyApp.Schema]\n```\n\n**Module-level schema:**\n\n```elixir\ndefmodule MyApp.Queries do\n  use GraphqlQuery, schema: MyApp.Schema\n\n  def get_users do\n    ~GQL\"\"\"\n    query { users { id name } }\n    \"\"\"\n  end\n\n  def get_user(user_id) do\n    # It is recommended to use GraphQL variables, this is just an example to showcase runtime validation with schema\n    gql [runtime: true], \"\"\"\n    query GetUserById { user(id: \"#{user_id}\") { name } }\n    \"\"\"\n  end\nend\n```\n\n---\n\n## Apollo Federation Support\n\nGraphQL Query supports **Apollo Federation v2** directives, allowing you to validate federated schemas that use directives like `@key`, `@shareable`, `@external`, and others.\n\n### Enabling Federation Support\n\nEnable federation validation by setting the `federation: true` option. This makes all Apollo Federation v2 directives available in your schema.\n\n**With sigil (using `F` modifier):**\n\n```elixir\n~GQL\"\"\"\nextend schema\n  @link(url: \"https://specs.apollo.dev/federation/v2.5\", import: [\"@key\", \"@shareable\"])\n\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String! @shareable\n}\n\"\"\"sF  # s = schema, F = federation\n```\n\n**With `gql` macro:**\n\n```elixir\ngql [type: :schema, federation: true], \"\"\"\nextend schema\n  @link(url: \"https://specs.apollo.dev/federation/v2.0\", import: [\"@key\"])\n\ntype Product @key(fields: \"id\") {\n  id: ID!\n  price: Float\n}\n\"\"\"\n```\n\n**With `gql_from_file` macro:**\n\n```elixir\ngql_from_file \"priv/graphql/federated_schema.graphql\", type: :schema, federation: true\n```\n\n**With `document_with_options`:**\n\n```elixir\ndocument_with_options type: :schema, federation: true do\n  ~GQL\"\"\"\n  extend schema @link(url: \"https://specs.apollo.dev/federation/v2.9\", import: [\"@key\"])\n  \n  type Order @key(fields: \"id\") {\n    id: ID!\n    total: Float\n  }\n  \"\"\"s\nend\n```\n\n**At module level:**\n\n```elixir\ndefmodule MyApp.FederatedSchema do\n  use GraphqlQuery, federation: true\n  \n  def schema do\n    ~GQL\"\"\"\n    extend schema @link(url: \"https://specs.apollo.dev/federation/v2.5\", import: [\"@key\"])\n    \n    type User @key(fields: \"id\") {\n      id: ID!\n      name: String!\n    }\n    \"\"\"s\n  end\nend\n```\n\n### Supported Federation Versions\n\nThe library supports multiple Apollo Federation v2 versions. Specify the version in your `@link` directive:\n\n- `v2.0` - Base Apollo Federation v2 directives\n- `v2.5` - Adds `@authenticated` and `@requiresScopes`\n- `v2.9` - Adds `@cost` and `@listSize`\n\nUnknown versions automatically fall back to standard validation without federation directives.\n\n### Implementation Note\n\nWhen `federation: true` is enabled, **all Apollo Federation directives are available** for use in your schema, regardless of what you specify in the `@link` import list. This simplified approach covers the vast majority of use cases and makes it easier to work with federated schemas.\n\nThe following directives are available:\n- Core directives: `@key`, `@requires`, `@provides`, `@external`, `@tag`, `@extends`, `@shareable`, `@inaccessible`, `@override`, `@composeDirective`, `@interfaceObject`\n- Authentication (v2.5+): `@authenticated`, `@requiresScopes`, `@policy`\n- Cost control (v2.9+): `@cost`, `@listSize`\n\n---\n\n## Formatter Integration\n\nAdd to `.formatter.exs`:\n\n```elixir\n[\n  inputs: [\"{lib,test,priv}/**/*.{ex,exs,graphql,gql}\"],\n  plugins: [GraphqlQuery.Formatter],\n  import_deps: [:graphql_query]\n]\n```\n\nNow `mix format` will:\n- Format `.graphql` and `.gql` files\n- Format `~GQL` sigils in Elixir code\n\n---\n\n## Manual API\n\nYou shouldn't need to use the manual API, but if you need to, you can do everything yourself.\n\nCheck the documentation of these modules if you want to know more about the manual API:\n- [GraphqlQuery.Document](https://hexdocs.pm/graphql_query/GraphqlQuery.Document.html)\n- [GraphqlQuery.Fragment](https://hexdocs.pm/graphql_query/GraphqlQuery.Fragment.html)\n- [GraphqlQuery.Validator](https://hexdocs.pm/graphql_query/GraphqlQuery.Validator.html)\n- [GraphqlQuery.Format](https://hexdocs.pm/graphql_query/GraphqlQuery.Format.html)\n\n---\n\n## Roadmap\n\n### Planned\n\n- [ ] When validation error, try to detect if it's in a fragment, and if it's an \"imported\" fragment, print the error in the fragment's location\n- [ ] Configure schemas with remote URLs to fetch, and have a mix task to check if the content differs\n- [ ] Optional compile-time validation via Mix task\n- [ ] Fix line reporting on validation errors on gql on expanded code\n\n\n### Done\n\n- [x] Validate queries with sigil\n- [x] Format queries with formatter plugin\n- [x] `gql` macro for dynamic queries\n- [x] `gql_from_file` macro for file-based queries\n- [x] Schema parsing and validation\n- [x] Custom Document and Fragment representation, with implementation for to_string and json with JSON and Jason\n- [x] Allow to set fragments in individual queries or per-module (`document_with_options` macro)\n- [x] Extract document info, and calculate if possible name and signature\n- [x] Improve non-compile time options detection and fallback to runtime/ignore\n- [x] GraphqlQuery.Schema with Absinthe schema\n\n---\n\n## License\nBeerware 🍺 — do whatever you want with it, but if we meet, buy me a beer. (This is essentially MIT-like. Use it freely, but if we meet, buy me a beer)\n\n\u003c!-- MDOC --\u003e\n\n---\n\n## Links\n- [GitHub](https://github.com/rockneurotiko/graphql_query)\n- [Hex.pm](https://hex.pm/packages/graphql_query)\n- [Docs](https://hexdocs.pm/graphql_query)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockneurotiko%2Fgraphql_query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frockneurotiko%2Fgraphql_query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockneurotiko%2Fgraphql_query/lists"}