GraphQL APIs with Absinthe: Building Powerful APIs in Elixir

Master the art of building GraphQL APIs with Absinthe in Elixir. Learn how to consume GraphQL services, perform schema stitching, and implement real-time data fetching with subscriptions.

14.7. GraphQL APIs with Absinthe

GraphQL has emerged as a powerful alternative to REST for building APIs, offering a flexible and efficient way to query and manipulate data. In the Elixir ecosystem, Absinthe is the go-to library for implementing GraphQL APIs. This section will guide you through the advanced concepts of building GraphQL APIs with Absinthe, focusing on consuming GraphQL services, schema stitching, and implementing real-time data fetching with subscriptions.

Introduction to GraphQL and Absinthe

GraphQL is a query language for APIs and a runtime for executing those queries by using a type system you define for your data. It allows clients to request only the data they need, reducing over-fetching and under-fetching issues common with REST APIs.

Absinthe is a robust GraphQL toolkit for Elixir, designed to help developers build powerful and flexible APIs. It integrates seamlessly with the Elixir ecosystem, leveraging its concurrency model and functional programming paradigm to deliver high-performance GraphQL services.

Consuming GraphQL Services

To consume GraphQL services, you can use clients like Absinthe.Plug to interact with GraphQL APIs. This section will demonstrate how to set up a GraphQL client in Elixir and make queries to a GraphQL server.

Setting Up Absinthe.Plug

Absinthe.Plug is a library that allows you to mount a GraphQL schema in a Plug application. It acts as a bridge between your Elixir application and the GraphQL server.

1# Add Absinthe.Plug to your mix.exs
2defp deps do
3  [
4    {:absinthe_plug, "~> 1.5"}
5  ]
6end

Creating a GraphQL Client

To create a GraphQL client, you need to define a schema and configure the endpoint to handle GraphQL requests.

 1# Define a simple schema
 2defmodule MyAppWeb.Schema do
 3  use Absinthe.Schema
 4
 5  query do
 6    field :hello, :string do
 7      resolve fn _, _ ->
 8        {:ok, "Hello, world!"}
 9      end
10    end
11  end
12end
13
14# Configure the endpoint
15defmodule MyAppWeb.Endpoint do
16  use Phoenix.Endpoint, otp_app: :my_app
17
18  plug Absinthe.Plug,
19    schema: MyAppWeb.Schema
20
21  plug Plug.Logger
22  plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json],
23                     pass: ["*/*"],
24                     json_decoder: Jason
25
26  plug :match
27  plug :dispatch
28end

Making GraphQL Queries

With the client set up, you can now make GraphQL queries to fetch data from the server.

 1# Example query
 2query = """
 3{
 4  hello
 5}
 6"""
 7
 8# Send the query to the server
 9response = MyAppWeb.Endpoint.call(%Plug.Conn{}, :get, "/graphql", query)
10
11IO.inspect(response)

Schema Stitching

Schema stitching is a technique used to combine multiple GraphQL schemas into a single unified schema. This is particularly useful when you have microservices or separate GraphQL APIs that you want to expose as a single API.

Implementing Schema Stitching

To implement schema stitching in Absinthe, you can use the Absinthe.Schema.Notation module to define and merge schemas.

 1defmodule MyAppWeb.StitchedSchema do
 2  use Absinthe.Schema.Notation
 3
 4  import_types MyAppWeb.Schema1
 5  import_types MyAppWeb.Schema2
 6
 7  query do
 8    import_fields :schema1_query
 9    import_fields :schema2_query
10  end
11end

Benefits of Schema Stitching

  • Unified API: Expose multiple services as a single API.
  • Modularity: Keep schemas modular and maintainable.
  • Reusability: Reuse types and fields across different schemas.

Subscriptions

Subscriptions in GraphQL allow clients to receive real-time updates from the server. Absinthe provides robust support for implementing subscriptions, enabling you to build real-time applications with ease.

Implementing Subscriptions

To implement subscriptions, you need to define subscription fields in your schema and use a PubSub system to broadcast updates.

 1defmodule MyAppWeb.Schema do
 2  use Absinthe.Schema
 3
 4  subscription do
 5    field :new_message, :message do
 6      config fn _, _ ->
 7        {:ok, topic: "messages"}
 8      end
 9    end
10  end
11end
12
13# Broadcasting updates
14MyAppWeb.Endpoint.broadcast("messages", "new_message", %{content: "Hello, world!"})

Real-Time Data Fetching

Subscriptions enable real-time data fetching, allowing clients to receive updates as soon as they occur.

  • Use Cases: Chat applications, live sports scores, stock market updates.
  • Efficiency: Reduce polling and improve performance.

Visualizing GraphQL with Absinthe

To better understand the flow of data in a GraphQL API built with Absinthe, let’s visualize the process using a sequence diagram.

    sequenceDiagram
	    participant Client
	    participant AbsinthePlug
	    participant GraphQLServer
	
	    Client->>AbsinthePlug: Send GraphQL Query
	    AbsinthePlug->>GraphQLServer: Resolve Query
	    GraphQLServer-->>AbsinthePlug: Return Data
	    AbsinthePlug-->>Client: Send Response

Diagram Description: This sequence diagram illustrates the interaction between a client, Absinthe.Plug, and a GraphQL server. The client sends a query to Absinthe.Plug, which resolves the query by communicating with the GraphQL server. The server returns the data, and Absinthe.Plug sends the response back to the client.

Key Considerations for GraphQL APIs with Absinthe

  • Performance: Optimize queries and use batching to reduce server load.
  • Security: Implement authentication and authorization to protect sensitive data.
  • Error Handling: Provide meaningful error messages and handle exceptions gracefully.

Elixir Unique Features

Elixir’s concurrency model and functional programming paradigm make it an excellent choice for building GraphQL APIs. Absinthe leverages these features to deliver high-performance, scalable APIs.

  • Concurrency: Handle multiple requests simultaneously with lightweight processes.
  • Fault Tolerance: Use OTP principles to build resilient systems.
  • Functional Programming: Write clean, maintainable code with pure functions and immutability.

Differences and Similarities with REST

While both GraphQL and REST are used to build APIs, they have key differences:

  • Flexibility: GraphQL allows clients to specify exactly what data they need, while REST has fixed endpoints.
  • Efficiency: GraphQL reduces over-fetching and under-fetching by allowing clients to request only the necessary data.
  • Complexity: GraphQL can be more complex to implement due to its flexible query language and schema requirements.

Try It Yourself

Experiment with the code examples provided in this section. Try modifying the schema, adding new fields, or implementing additional subscriptions. Explore the capabilities of Absinthe and see how it can enhance your Elixir applications.

Knowledge Check

  • What are the benefits of using GraphQL over REST?
  • How does Absinthe leverage Elixir’s concurrency model?
  • What is schema stitching, and why is it useful?
  • How do subscriptions enable real-time data fetching?

Summary

In this section, we’ve explored the advanced concepts of building GraphQL APIs with Absinthe in Elixir. We’ve covered consuming GraphQL services, schema stitching, and implementing real-time data fetching with subscriptions. By leveraging Elixir’s unique features and Absinthe’s powerful toolkit, you can build flexible, efficient, and scalable APIs.

Remember, this is just the beginning. As you progress, you’ll discover more advanced techniques and patterns for building GraphQL APIs in Elixir. Keep experimenting, stay curious, and enjoy the journey!

Quiz: GraphQL APIs with Absinthe

Loading quiz…
Revised on Thursday, April 23, 2026