{"id":16791754,"url":"https://github.com/mhemrg/qpi","last_synced_at":"2025-04-10T23:32:53.534Z","repository":{"id":57046471,"uuid":"102711628","full_name":"mhemrg/qpi","owner":"mhemrg","description":"A query language for dynamically fetching data from Laravel Eloquent models","archived":false,"fork":false,"pushed_at":"2017-12-29T10:43:00.000Z","size":44,"stargazers_count":11,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T20:21:41.154Z","etag":null,"topics":["laravel","qpi","query-language","schema"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mhemrg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-07T08:27:22.000Z","updated_at":"2021-04-24T04:48:59.000Z","dependencies_parsed_at":"2022-08-24T03:40:34.692Z","dependency_job_id":null,"html_url":"https://github.com/mhemrg/qpi","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhemrg%2Fqpi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhemrg%2Fqpi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhemrg%2Fqpi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhemrg%2Fqpi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mhemrg","download_url":"https://codeload.github.com/mhemrg/qpi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248316881,"owners_count":21083515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","qpi","query-language","schema"],"created_at":"2024-10-13T08:35:46.456Z","updated_at":"2025-04-10T23:32:53.512Z","avatar_url":"https://github.com/mhemrg.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Qpi\nQpi is a query language for APIs and a runtime for fulfilling those queries with your existing data. Qpi provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time.\n\n\u003e\u003e\u003e\nFirst of all, you should know that Qpi is an idea and you can implement it in your own language. This project is just a Qpi implementation for Laravel.\n\u003e\u003e\u003e\n\n## Usage\n\n**1) Install it:**\n\n```\ncomposer require qpi/laravel\n```\n\n**2) Add to providers**\n\nOpen your Laravel config file `config/app.php` and add the following lines.\n\nIn the `$providers` array add the service provider for this package.\n```php\nNavac\\Qpi\\QpiServiceProvider::class,\n```\n\n**3) Update autoload:**\n```\ncomposer dumpautoload\n```\n\n## Configuration\nFirst, you need to publish configuration file.\n```\nphp artisan vendor:publish\n```\nThe configuration file is copied to `config/qpi.php`.\n\n## Registering models\nTo give access to the models, you have to register your models in `config/qpi.php`.\n\n```php\nreturn [\n\n  /*\n  |--------------------------------------------------------------------------\n  | Qpi Models\n  |--------------------------------------------------------------------------\n  |\n  | The models listed here will be available for Qpi to make responses.\n  |\n  */\n  'models' =\u003e [\n    'user' =\u003e App\\User::class,\n    'product' =\u003e App\\Product::class,\n  ]\n\n];\n```\n\n## Quick Tutorial\nThis package will introduce two new routes to your app. `/query/{query}` and `/schema`.\n\nIf you want to make a query, just use the first endpoint like this:\n```\n/query/{ category{id, name} }\n```\nAnd if you want to see the manual of your models, use the second endpoint: `/schema`.\n\n## The Query Language\nNow, you just need to know how to use it. As I said, it's query language and you have to need to learn it to make your queries. It's a simple language with few tips. Please follow the next steps.\n\nSo let's start.\nEach query must be between curly braces:\n```\n{\n    ...the body of query\n}\n```\n\nIn the body of each query you have to define which model you want to fetch:\n```\n{\n    book {\n    }\n}\n```\nIn the above query, we want to fetch the `book` model. Someone may ask, what are the next curly braces? Those curly braces are just to tell Qpi which fields of that model you want to fetch.\nIf I want to complete my query,  It will be like this:\n```\n{\n    book {\n        title,\n        created_at\n    }\n}\n```\nIf you don't specify any field, it will return all of available fields.\n\n**Nested queries:**\nImagine want to fetch the author of each book. So how can we do that?\n```\n{\n    book {\n        title,\n        created_at,\n        author {\n            name,\n            age\n        }\n    }\n}\n```\nYou see that Qpi supports making queries for nested models.\n\n**Limiting results:**\nIf you want to specify how many records to fetch, you can do that like this:\n```\n{\n    book (0:5) {\n        title,\n        created_at,\n        author {\n            name,\n            age\n        }\n    }\n}\n```\nI used above syntax to tell Qpi that I want to limit results to just 5 records. In other words, the parenthesis syntax is just this: `(offset, limit)`.\n\n**Where statements:**\n```\n{\n    book (0:5) [id=5] {\n        title,\n        created_at,\n        author {\n            name,\n            age\n        }\n    }\n}\n```\nYou have to use brackets in order to write your where statements.\n\n*Operators:*\n\n| Operator     | Name         | Example        |\n|--------------|--------------|----------------|\n| =            | Equal        | id=5           |\n| \u003e            | Greater than | id\u003e2           |\n| \u003c            | Less than    | id\u003c6           |\n| !            | Not equal    | id!6           |\n| ~            | Like         | name~'john%'   |\n| \u0026#124;       | OR           | id\u003c6\u0026#124;id\u003e3 |\n| \u0026            | AND          | id=6\u0026id=3      |\n\n\n**Order by:**\n```\n{\n    book (0:5) [id=5] {\n        title,\n        created_at:1,\n        author {\n            name,\n            age\n        }\n    }\n}\n```\nYou can add a colon after every field witch you want to order results by it. After colon you have to tell Qpi the direction. `1` for ASC and `0` for DESC.\n\n**Query batching:**\n\nWith a single request, you can fetch all of your needs. Just put your queries into curly braces.\n```\n{\n    book {\n        title,\n        created_at\n    }\n}\n{\n    category {\n        id,\n        name\n    }\n}\n```\nAbove, you see two different queries but you can fetch it with a single request.\n\n## Authorization\nTo enable authorization for models, you should add `qpiAccess` method to each model. Qpi will call this method in each request that want's to have access to that model and if the model throws an error, Qpi will reject the request.\n\n```php\nclass Product extends Model {\n\n    public function qpiAccess() {\n        if(request()-\u003eheader('Authorization') != 'the valid token') {\n            throw new \\Exception('Authorization failed.');\n        }\n    }\n\n}\n```\n\nNote that Qpi will inject dependencies to this method.\n\n# Schema (Comming soon...)\nYour users can make request to `/schema` to see the schema of models. In order to do that, your models should have two optional static properties `$qpiProps` and `$qpiRelations`.\n```php\nclass Product extends Model {\n    public static $qpiProps = [\n        'id' =\u003e 'The id',\n        'name' =\u003e 'The name of the product',\n        ...\n    ];\n\n    public static $qpiRelations = [\n        'tags' =\u003e 'Related tags of product',\n        ...\n    ];\n    \n    ...\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhemrg%2Fqpi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmhemrg%2Fqpi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhemrg%2Fqpi/lists"}