tina4stack / tina4php-graphql
Lightweight GraphQL engine for Tina4 PHP — recursive descent parser, executor, auto-schema from ORM
v2.0.1
2026-03-14 18:23 UTC
Requires
- php: >=8.1
Requires (Dev)
- phpunit/phpunit: ^9
README
Lightweight GraphQL engine for the Tina4 PHP framework. Built from scratch with no external dependencies — recursive descent parser, depth-first executor, and auto-schema generation from ORM objects.
Installing
composer require tina4stack/tina4php-graphql
Requirements
- PHP >= 8.1
Usage
Simple Queries
$schema = new \Tina4\GraphQLSchema(); $schema->addQuery('hello', [ 'type' => 'String', 'resolve' => fn() => 'Hello World!', ]); $schema->addQuery('user', [ 'type' => 'User', 'args' => ['id' => ['type' => 'ID']], 'resolve' => fn($root, $args) => ['id' => $args['id'], 'name' => 'Andre'], ]); $graphql = new \Tina4\GraphQL($schema); $result = $graphql->execute('{ hello user(id: 1) { name } }'); // $result = ['data' => ['hello' => 'Hello World!', 'user' => ['name' => 'Andre']]]
Auto-Schema from ORM
The killer feature — register ORM classes and get full CRUD automatically:
$schema = new \Tina4\GraphQLSchema(); $schema->fromORM(Customer::class); $schema->fromORM(Order::class); // Generates automatically: // Queries: customer(id), customers(limit, offset) // Mutations: createCustomer(input), updateCustomer(id, input), deleteCustomer(id)
Tina4 Route Integration
$schema = new \Tina4\GraphQLSchema(); $schema->fromORM(Customer::class); \Tina4\GraphQLRoute::register($schema); // POST /graphql with JSON body: // { "query": "{ customers(limit: 10) { id name email } }" }
Mutations
$schema->addMutation('createUser', [ 'type' => 'User', 'args' => ['name' => ['type' => 'String!'], 'email' => ['type' => 'String!']], 'resolve' => function ($root, $args) { $user = new User(); $user->name = $args['name']; $user->email = $args['email']; $user->save(); return ['id' => $user->id, 'name' => $user->name, 'email' => $user->email]; }, ]);
Variables
query GetUser($id: ID!) { user(id: $id) { name email } }
$result = $graphql->execute($query, ['id' => 42]);
Fragments
fragment UserFields on User { id name email } { users { ...UserFields } }
HTTP Handler
$graphql = new \Tina4\GraphQL($schema); $jsonResponse = $graphql->handleRequest(file_get_contents('php://input'));
Architecture
| Class | Purpose |
|---|---|
GraphQL |
Main entry — parse, execute, return result |
GraphQLParser |
Recursive descent parser — query string to AST |
GraphQLExecutor |
Walks AST, calls resolvers, builds response |
GraphQLSchema |
Type definitions, query/mutation registry |
GraphQLType |
Type system — scalars, objects, lists, non-null |
GraphQLRoute |
Register /graphql POST endpoint in Tina4 |
Supported Features
- Queries and mutations
- Nested field resolution
- Arguments (string, int, float, boolean, enum)
- Variable definitions and resolution
- Fragment definitions and spreads
- Aliases
- Comments
- List types
- Error collection (non-halting)
- Auto-schema from Tina4 ORM
Running Tests
composer test
Our Sponsors
Sponsored with 🩵 by Code Infinity
Supporting open source communities • Innovate • Code • Empower