Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Graphql Relay Laravel Package

nuwave/laravel-graphql-relay

Adds Relay-style cursor pagination and global object identification to Laravel GraphQL applications, including connection fields, cursor encoding, and node interfaces. Helps you build standards-compliant GraphQL APIs that work smoothly with Relay and other GraphQL clients expecting pagination and gl...

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm compatibility before you write any schema. The single most important first step: this package's last release was 2016-11-17 and the repository is archived. Modern Lighthouse (v4+) ships Relay support natively — cursor pagination on @paginate (type: CONNECTION), @node, the Node interface, and the GlobalId scalar — so this package is only viable if you are pinned to an old Lighthouse (roughly the v1/v2 era it was authored against). Run:

composer require nuwave/laravel-graphql-relay

and read the dependency-conflict output before doing anything else. A failed install is your signal to stop and use Lighthouse's built-in directives instead of fighting the constraint solver.

Where to look first, in order:

  1. The package source / README for its service provider — that is what registers the extra directives and Relay types into Lighthouse. Nothing happens without it being discovered.
  2. config/lighthouse.php and your schema namespace — the package operates at the directive level, so its effect is only visible in the schema and the generated types.
  3. Lighthouse's own docs for @paginate, @node, and GlobalId — cross-reference these, because behaviour overlaps and this package's docs are thin.

First use case: take an existing list field (posts: [Post!]! @all) that a Relay client can't consume, and convert it into a cursor-paginated connection exposing first / after / last / before, returning edges { node } and pageInfo { hasNextPage endCursor }. That single conversion exercises the package's entire value proposition: Relay-compliant connections without hand-authoring PostConnection, PostEdge, and PageInfo types.

Implementation Patterns

Connection via the @paginate directive. The core workflow is to attach the directive to a query field and let it emit the connection wrapper:

type Query {
  posts(first: Int, after: String, last: Int, before: String): PostConnection @paginate
}

The client then walks pages with posts(first: 25, after: $endCursor). This is the pattern you'll repeat for every list field a Relay client touches.

Global object identification via the Node interface. Declare the interface, have your object types implement it, and expose a single lookup entry point:

interface Node { id: ID! }

type Post implements Node {
  id: ID!
  title: String!
}

type Query {
  node(id: ID!): Node
}

The day-to-day workflow: clients cache by the opaque id, then refetch any object through node(id:) regardless of its concrete type. The package handles decoding the global ID back to (type, localId) and dispatching to the right resolver.

Paginate Eloquent relationships directly. Instead of a top-level query, apply the same directive to a relationship field so nested collections paginate out of the box (e.g. Post { comments(first, after): CommentConnection @paginate }). This is where the package saves the most boilerplate — you don't wire cursors by hand per relation.

Integration tips:

  • Keep the schema schema-first and modular; the connection/edge types are generated, so don't hand-declare them or you'll get duplicate-type validation errors.
  • Pass cursors back to the server verbatim — treat them as opaque strings in your client code. Never construct or parse them client-side.
  • Test with GraphiQL/Altair during development so you can eyeball pageInfo and confirm hasNextPage / hasPreviousPage behave as expected before wiring a real Relay client.
  • Use a stable sort key (add an id tiebreaker) so cursor positions remain deterministic across pages.

Gotchas and Tips

The archived status is the headline gotcha. No security patches, no compatibility fixes, and directive signatures changed across major Lighthouse rewrites. Even if it installs, expect subtle breakage against anything but the contemporary Lighthouse version.

Prefer Lighthouse's native Relay features for new work. The mental model you learn here transfers directly:

type Query {
  posts(first: Int, after: String): PostConnection @paginate(type: CONNECTION)
  node(id: ID!): Node @node
}

with GlobalId and the Node interface provided by Lighthouse itself. The main "extension point" for most teams is therefore not the package but a migration: replace its directives with the native equivalents and drop the dependency.

Global ID decoding. If node(id:) returns null, it's usually a malformed or URL-mangled global ID (they're typically base64 of Type:localId). Log the raw value; base64 decoding silently fails on padding/newline corruption.

Cursor semantics are the most error-prone area. last / before (backward pagination) behave differently from first / after and are easy to misuse; verify hasPreviousPage explicitly. Mixing directions in one query is a common source of empty pages.

Performance. Cursor pagination on large tables can still degrade if the underlying implementation falls back to offsets. Watch query plans and ensure a stable, indexed ordering column.

Debugging checklist, in order of likelihood: (1) service provider not auto-discovered / not registered → directive unknown; (2) schema validation error from a hand-declared connection type colliding with the generated one; (3) wrong Lighthouse version → directive argument mismatch; (4) cursor encoding issue → empty node results.

Config quirk: the package relies on Lighthouse's directive registration path, so changes to Lighthouse's schema/config layout (e.g. custom directive namespaces) will strand it — another reason to avoid building long-lived features on it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo