PHPackages                             shish/gqla - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. shish/gqla

ActiveLibrary[API Development](/categories/api)

shish/gqla
==========

A set of annotations for generating graphql APIs

v1.2.0(2mo ago)826.5k↓44.8%MITPHPPHP ^8.4CI passing

Since Feb 25Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/shish/gqla)[ Packagist](https://packagist.org/packages/shish/gqla)[ Docs](https://github.com/shish/gqla)[ RSS](/packages/shish-gqla/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (8)Used By (0)

gqla
====

[](#gqla)

A GraphQL schema generator based on PHP Attributes

Because when your webapp already has objects for internal use, you shoudn't need to rewrite or duplicate everything in order to query those objects via graphql :)

The schemas generated here are based on , so once you've generated a schema, look at the docs over there for how to make use of it

Example:

```
use GQLA\Type;
use GQLA\Field;
use GQLA\Query;
use GQLA\Mutation;

// To create a new GraphQL Type, expose a PHP class
#[Type]
class Post {
    // To add fields to that type, expose PHP class properties
    #[Field]
    public string $title;
    #[Field]
    public string $body;

    // If you don't want the field to be part of your API,
    // don't expose it
    public int $author_id;

    // If your field is more complicated than a property,
    // expose a PHP function and it will be called as needed
    #[Field(name: "author")]
    public function get_author(): User {
        return User::by_id($this->author_id);
    }

    // To add a new query or mutation, you can extend
    // the base Query or Mutation types
    #[Query(name: "posts", type: "[Post!]!")]
    public static function search_posts(string $text): array {
        // SELECT * FROM posts WHERE text LIKE "%{$text}%";
    }
}

#[Type]
class User {
    #[Field]
    public string $name;
}

#[Type]
class Comment {
    #[Field]
    public string $text;
    public int $post_id;
    public int $author_id;
    #[Field]
    public function author(): User {
        return User::by_id($this->author_id);
    }
    #[Field(deprecationReason: "Use author subfield")]
    public function author_name(): string {
        return User::by_id($this->author_id)->name;
    }

    // Note that even if the Comment class comes from a third-party
    // plugin, it can still add a new "comments" field onto the
    // first-party "Post" object type.
    #[Field(extends: "Post", type: "[Comment!]!")]
    public function comments(Post $post): array {
        // SELECT * FROM comments WHERE post_id = {$post->id}
    }
}
```

Then `new \GQLA\Schema();` will search for all annotated objects and return a graphql schema like:

```
type Post {
    title: String!
    body: String!
    author: User!
    comments: [Comment!]!
}

type User {
    name: String!
}

type Comment {
    text: String!
    author: User!
    author_name: String @deprecated(reason: "Use author subfield")
}

type Query {
    search_posts(text: String!): [Post!]!
}
```

So you can send a query like

```
{
    search_posts(text: "Hello") {
        title
        body
        author {
            name
        }
        comments {
            text
        }
    }
}
```

And get a response like

```
{
    "data": {
        "posts": [
            {
                "title": "Hello world!",
                "body": "This is the first post in my blog",
                "author": {
                    "name": "Shish",
                },
                "comments": [
                    { "text": "Nice first post!" },
                    { "text": "It works :D" },
                ],
            }
        ]
    }
}
```

API
---

[](#api)

These annotations have several common parameters:

- `name`: Give a specific name to this type / field (default: Use the class / property / function name)
- `type`: Give a specific type to the field (default: infer this from the PHP-types-to-GraphQL-types map)
    - Note that if your PHP type is `array`, then you must specify `type` with something more specific for GraphQL, for example: ```
        #[Field(type: "[String!]!")]
        function get_tags(): array {
            return ["foo", "bar"];
        }
        ```
- `args`: Override the inferred types for any function arguments
    - As with type, note that this is required whenever a PHP function accepts an array as input, for example: ```
        #[Field(args: ["tags" => "[String!]!"])]
        function get_first_post_with_tags(array $tags): Post {
            return ...;
        }
        ```
- `extends`: By default, an exposed field on an exposed object will be added as a field of that object. You can also extend your other objects (eg, a "likes" plugin could add a `number_of_likes` field onto your `BlogPost` object)
- `description`: Add a description to your GraphQL schema for anybody who wants to develop client apps
- `deprecationReason`: Mark this field as deprecated

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance86

Actively maintained with recent releases

Popularity33

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~249 days

Total

4

Last Release

66d ago

PHP version history (3 changes)v1.0.0PHP ^8.1

v1.1.0PHP ^8.2

v1.2.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/a40f5d114b344f735652e4ccc988a618ef5ee2e85a644abeb7e20e92f4c740d5?d=identicon)[shish](/maintainers/shish)

---

Top Contributors

[![shish](https://avatars.githubusercontent.com/u/40659?v=4)](https://github.com/shish "shish (54 commits)")

---

Tags

graphql

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/shish-gqla/health.svg)

```
[![Health](https://phpackages.com/badges/shish-gqla/health.svg)](https://phpackages.com/packages/shish-gqla)
```

###  Alternatives

[nuwave/lighthouse

A framework for serving GraphQL from Laravel

3.5k10.7M93](/packages/nuwave-lighthouse)[overblog/graphql-bundle

This bundle provides tools to build a GraphQL server in your Symfony App.

8027.9M28](/packages/overblog-graphql-bundle)[aimeos/ai-admin-graphql

Aimeos Admin GraphQL API extension

944100.0k4](/packages/aimeos-ai-admin-graphql)[mll-lab/graphql-php-scalars

A collection of custom scalar types for usage with https://github.com/webonyx/graphql-php

1394.2M28](/packages/mll-lab-graphql-php-scalars)[ivome/graphql-relay-php

A PHP port of GraphQL Relay reference implementation

271632.4k5](/packages/ivome-graphql-relay-php)[overblog/graphql-php-generator

GraphQL types generator

29518.9k](/packages/overblog-graphql-php-generator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
