phpnomad/graphql is an engine-agnostic GraphQL abstraction for PHPNomad. It defines the contracts your application writes against (TypeDefinition, FieldResolver, GraphQLStrategy, and ResolverContext) so that type definitions and resolvers stay portable across whichever GraphQL engine you plug in underneath. Your schema code depends only on these interfaces, which keeps it decoupled from the runtime library and easy to test in isolation.
The package itself ships five interfaces and a single exception class, not a runtime. The recommended concrete strategy lives in phpnomad/webonyx-integration, which adapts these interfaces to webonyx/graphql-php. Install both together when you want a working GraphQL layer.
composer require phpnomad/graphqlFor a concrete engine, also pull in the webonyx strategy:
composer require phpnomad/webonyx-integrationA TypeDefinition returns an SDL string and a resolver map. Only fields that need custom logic require a resolver entry. All other fields fall back to the engine's default property resolution.
<?php
namespace MyApp\GraphQL\Types;
use MyApp\GraphQL\Resolvers\BookByIdResolver;
use PHPNomad\GraphQL\Interfaces\TypeDefinition;
class BookType implements TypeDefinition
{
public function getSdl(): string
{
return <<<SDL
type Book {
id: ID!
title: String!
author: String!
}
extend type Query {
book(id: ID!): Book
}
SDL;
}
public function getResolvers(): array
{
return [
'Query' => [
'book' => BookByIdResolver::class,
],
];
}
}A FieldResolver is a single-method class that receives the root value, the field arguments, and a ResolverContext carrying the PHPNomad HTTP request.
<?php
namespace MyApp\GraphQL\Resolvers;
use MyApp\Books\BookRepository;
use PHPNomad\GraphQL\Interfaces\FieldResolver;
use PHPNomad\GraphQL\Interfaces\ResolverContext;
class BookByIdResolver implements FieldResolver
{
public function __construct(protected BookRepository $books)
{
}
public function resolve(mixed $rootValue, array $args, ResolverContext $context): mixed
{
return $this->books->findById((string) $args['id']);
}
}Register each TypeDefinition with the GraphQLStrategy supplied by the integration package, then call execute() with a query string, a variables array, and the context. Because the resolver map references class strings, the strategy can hydrate resolvers through the DI container when they run.
TypeDefinition: SDL for a type plus a resolver map for fields that need custom logicFieldResolver: a singleresolve()method taking the root value, field arguments, and aResolverContextGraphQLStrategy: the engine adapter responsible for registering type definitions and executing queriesResolverContext: carries the PHPNomad HTTPRequestthrough to resolvers so they can reach request-scoped stateHasTypeDefinitions: marker interface for classes that group a set ofTypeDefinitionclass strings for registrationGraphQLException: base exception the package throws when something goes wrong in the GraphQL layer
Full PHPNomad documentation lives at phpnomad.com. For the concrete engine that pairs with this package, see phpnomad/webonyx-integration and the upstream webonyx/graphql-php documentation.
MIT, see LICENSE for the full text.