{"id":13499276,"url":"https://github.com/railt/railt","last_synced_at":"2025-04-12T21:25:46.474Z","repository":{"id":57046636,"uuid":"91753282","full_name":"railt/railt","owner":"railt","description":"⚡️ A PHP GraphQL Framework","archived":false,"fork":false,"pushed_at":"2023-10-18T00:10:42.000Z","size":7878,"stargazers_count":361,"open_issues_count":16,"forks_count":18,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-04T00:41:19.012Z","etag":null,"topics":["application","compiler","framework","graphql","graphql-php","language","monorepo","php","php7","railt","sdl"],"latest_commit_sha":null,"homepage":"https://railt.org","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/railt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-05-19T01:37:11.000Z","updated_at":"2024-12-14T12:46:31.000Z","dependencies_parsed_at":"2023-10-16T08:37:34.622Z","dependency_job_id":"f8257de0-0762-444e-bef0-8b1dfe3745cf","html_url":"https://github.com/railt/railt","commit_stats":{"total_commits":1047,"total_committers":14,"mean_commits":74.78571428571429,"dds":0.2015281757402101,"last_synced_commit":"a034662e0f895b96d63fc69efc5d6ffa132a22b9"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/railt%2Frailt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/railt%2Frailt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/railt%2Frailt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/railt%2Frailt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/railt","download_url":"https://codeload.github.com/railt/railt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248633326,"owners_count":21136855,"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":["application","compiler","framework","graphql","graphql-php","language","monorepo","php","php7","railt","sdl"],"created_at":"2024-07-31T22:00:31.775Z","updated_at":"2025-04-12T21:25:46.445Z","avatar_url":"https://github.com/railt.png","language":"PHP","funding_links":[],"categories":["Libraries","PHP"],"sub_categories":["PHP Libraries"],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://railt.org\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/31258828?s=300\" width=\"150\" alt=\"Railt\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://packagist.org/packages/railt/railt\"\u003e\u003cimg src=\"https://poser.pugx.org/railt/railt/require/php?style=for-the-badge\" alt=\"PHP 8.1+\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://railt.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-site-6f4ca5.svg?style=for-the-badge\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAclBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9eWEHEAAAAJXRSTlMAoBzg8fxU9iFgsvjQwblyZdQYrYR0a1oT6dqlkH93TjQNC6N2001YMwAAAM5JREFUOMvNUtkOgzAMS3pwdMA4BjvZxfz/v7hOIEAt2hMP+MWN4kRRbdoYxMfIMJSmFsvtTmOA5gVJoLADkigqYB8qcPsNUOVQpd2kkFdA48wDe8rQkkWLjPbAfIedsv2T1uWvKLU+WYWa39HBEB2R9lWKI1EFphUhD5QpyqXLo4DTd4gns8ujIA6Dc3G/xC6PggjJ9ZYgcnl2BOIHpMcTGOK1Y4/XBPtfbcB/zapHs3y7D5PdfmBEHxgDNMuRK6bIeRDshtaX1EPsS9oWvv3QFx9Wvu0UAAAAAElFTkSuQmCC\" alt=\"railt.org\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://discord.gg/ND7SpD4\"\u003e\u003cimg src=\"https://img.shields.io/badge/discord-chat-6f4ca5.svg?style=for-the-badge\u0026logo=discord\u0026logoColor=ffffff\" alt=\"Discord\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/railt/railt\"\u003e\u003cimg src=\"https://poser.pugx.org/railt/railt/v?style=for-the-badge\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/railt/railt\"\u003e\u003cimg src=\"https://poser.pugx.org/railt/railt/v/unstable?style=for-the-badge\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://raw.githubusercontent.com/railt/railt/master/LICENSE.md\"\u003e\u003cimg src=\"https://poser.pugx.org/railt/railt/license?style=for-the-badge\" alt=\"License MIT\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/railt/railt/actions?workflow=Testing\"\u003e\u003cimg src=\"https://github.com/railt/railt/workflows/tests/badge.svg\" alt=\"Testing\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Introduction\n\nProject idea is clean and high-quality code.\n\nUnlike most (all at the moment) implementations, like [webonyx](https://github.com/webonyx/graphql-php),\n[youshido](https://github.com/youshido-php/GraphQL) or [digitalonline](https://github.com/digiaonline/graphql-php)\nthe Railt contains a completely own implementation of the GraphQL SDL parser\nwhich is based on [EBNF-like grammar](https://github.com/railt/railt/tree/master/libs/sdl/resources/grammar). \nThis opportunity allows not only to have the \n[original implementation of the language](https://facebook.github.io/graphql/draft/) and to\nkeep it always up to date, but also to implement [a new backward compatible\nfunctionality](https://github.com/railt/railt/projects/1) that is not available\nto other implementations.\n\nGoal of Railt:\n- Do not repeat the mistakes made in the JS-based implementations.\n- Implement a modern and convenient environment for PHP developers.\n- Implement easy integration into any ready-made solutions based on PSR.\n- Provide familiar functionality (including dependency injection, routing, etc.).\n\n## Installation\n\n- `composer require railt/railt`\n\n## Quick Start\n\nThis tutorial helps you:\n\n- Obtain a basic understanding of GraphQL principles.\n- Define a GraphQL schema that represents the structure of your data set.\n- Run an instance of Railt Application that lets you execute queries\n  against your schema.\n\nThis tutorial assumes that you are familiar with the command line and PHP and\nhave installed a recent PHP (v8.1+) version.\n\n### Step 1: Create a new project\n\n1. From your preferred development directory, create a directory for a new\n   project and `cd` into it:\n\n```bash\nmkdir railt-example\ncd railt-example\n```\n\n2. Initialize a new project with Composer:\n\n```bash\ncomposer init\ncomposer require railt/railt dev-master@dev\n```\n\n\u003e Your project directory now contains a `composer.json` file.\n\n\u003e Please note that in case of installation errors related to installing\n\u003e the dev version (_\"The package is not available in a stable-enough version\n\u003e according to your minimum-stability setting\"_), you need to specify\n\u003e `\"minimum-stability\": \"dev\"` in `composer.json` file.\n\u003e\n\u003e See more at [https://getcomposer.org/doc/04-schema.md#minimum-stability](https://getcomposer.org/doc/04-schema.md#minimum-stability)\n\nApplications that run Railt Application may require two top-level dependencies:\n\n- `railt/webonyx-executor` - An executor that provides a\n  [webonyx/graphql-php](https://github.com/webonyx/graphql-php) bridge for\n  launching and processing GraphQL requests.\n- `railt/router-extension` - A router extension that provides a convenient way\n  to delegate GraphQL requests to controller instances.\n\n\u003e Alternatively, you can install all components separately:\n\u003e ```bash\n\u003e composer require railt/factory railt/webonyx-executor railt/router-extension\n\u003e ```\n\n### Step 2: Define your GraphQL schema\n\nEvery GraphQL application (including Railt) uses a schema to define the\nstructure of data that clients can query. In this example, we'll create an\napplication for querying a collection of users by `id` and `name`.\n\nOpen `index.graphqls` in your preferred code editor and paste the following\ninto it:\n\n```graphql\n# Comments in GraphQL strings (such as this one)\n# start with the hash (#) symbol.\n\n# This \"User\" type defines the queryable fields for\n# every user in our data source.\ntype User {\n    id: ID\n    name: String\n}\n\n# The \"Query\" type is special: it lists all of the\n# available queries that clients can execute, along with\n# the return type for each. In this case, the \"books\"\n# query returns an array of zero or more Books (defined above).\ntype Query {\n    users: [User]\n}\n```\n\nNow just open (create) the `index.php` file and paste the following into it:\n\n```php\n\u003c?php\n\nrequire __DIR__ . '/vendor/autoload.php';\n\n//\n// Create An Application\n//\n$application = new Railt\\Foundation\\Application(\n    executor: new Railt\\Executor\\Webonyx\\WebonyxExecutor(),\n);\n\n$application-\u003eextend(new Railt\\Extension\\Router\\DispatcherExtension());\n\n//\n// Creating a connection instance that will process\n// incoming requests and return responses.\n//\n$connection = $application-\u003econnect(\n    schema: new \\SplFileInfo(__DIR__ . '/index.graphqls'),\n);\n```\n\nThis snippet defines a simple, valid GraphQL schema. Clients will be able to\nexecute a query named `users`, and our server will return an array of zero\nor more `User`s.\n\n#### Step 2.1: Schema health check\n\nTo health check an application, you can create a `GraphQLRequest` instance\nmanually by passing the request object with the desired GraphQL query string.\n\n```php\n//\n// Passing a request to the specified connection.\n// \n$response = $connection-\u003ehandle(\n    request: new \\Railt\\Http\\GraphQLRequest(\n        query: '{ users { id, name } }',\n    ),\n);\n\ndump($response-\u003etoArray());\n\n//\n// Expected Output:\n//\n// array:1 [\n//   \"data\" =\u003e array:1 [\n//     \"users\" =\u003e []\n//   ]\n// ]\n//\n```\n\n### Step 3: Define controller\n\nResolvers tell Railt Application how to fetch the data associated with a\nparticular type. Because our `User` array is hardcoded, the corresponding\nresolver is straightforward.\n\nCreate a controller file with a `UserController` class, for example with\na `index()` method and the following code:\n\n```php\n\u003c?php\n\nclass UserController\n{\n    public function index(): iterable\n    {\n        return [\n            ['id' =\u003e 1, 'name' =\u003e 'Vasya'],\n            ['id' =\u003e 2, 'name' =\u003e 'Petya'],\n        ];\n    }\n}\n```\n\n\u003e Make sure that this class is available for autoloading or the file is\n\u003e included in the `index.php`.\n\n### Step 4: Bind field to controller action\n\nWe've defined our data set, but Railt application doesn't know that it should\nuse that data set when it's executing a query. To fix this, we create a route.\n\nRoute tell Railt how to fetch the data associated with a particular type.\nBecause our `User` array is hardcoded, the corresponding route is\nstraightforward.\n\nAdd the following `@route` directive to the bottom of your `index.graphqls` file:\n\n```graphql\n# ...\ntype User {\n    id: ID\n    name: String\n}\n\n# ...\ntype Query {\n    users: [User]\n        # Route directive can be defined here\n        @route(action: \"UserController-\u003eindex\")\n}\n```\n\n### Step 5: Working with HTTP\n\nTo pass the request data and send the response, we must complete\nour `index.php` file.\n\n\u003e {tip} In the case that you use [Symfony](https://symfony.com/doc/current/introduction/http_fundamentals.html),\n[Laravel](https://laravel.com/docs/10.x/requests) or another http layer\n(for example, [psr-7](https://www.php-fig.org/psr/psr-7/)), then you can\norganize data acquisition according to the provided framework API and/or\nspecification.\n\n```php\n$data = json_decode(file_get_contents('php://input'), true);\n\n$response = $connection-\u003ehandle(\n    request: new \\Railt\\Http\\GraphQLRequest(\n        query: $data['query'] ?? '',\n        variables: $data['variables'] ?? [],\n        operationName: $data['operationName'] ?? null,\n    ),\n);\n\n$json = json_encode($response-\u003etoArray());\n\nheader('Content-Type: application/json');\nheader('Access-Control-Allow-Origin: *');\n\necho $json;\n```\n\n### Step 6: Start the server\n\nWe're ready to start our server! Run the following command from your\nproject's root directory:\n\n```bash\nphp -S 127.0.0.0:80\n```\n\nYou should now see the following output at the bottom of your terminal:\n\n```bash\nPHP 8.2.6 Development Server (http://127.0.0.1:80) started\n```\n\nWe're up and running!\n\n### Step 7: Execute your first query\n\nWe can now execute GraphQL queries on our server. To execute our first query,\nwe can use [Apollo Sandbox](https://studio.apollographql.com/sandbox/),\n[GraphQL Playground](https://www.graphqlbin.com/v2/new) or something else.\n\nOur server supports a single query named `users`. Let's execute it!\n\nHere's a GraphQL query string for executing the `users` query:\n```graphql\n{\n  users {\n    id\n    name\n  }\n}\n```\n\nPaste this string into the query panel and click the \"send request\" button (The\nGraphQL interface and panel layout may depend on the platform/client you are\nusing). The results (from our hardcoded data set) appear in the response panel:\n\n![/img/get-started-request.png](https://railt.org/img/get-started-request.png)\n\n\u003e One of the most important concepts of GraphQL is that clients can choose\nto query only for the fields they need. Delete `name` from the query string\nand execute it again. The response updates to include only the `id` field for\neach `User`!\n\n\n## Learning Railt\n\nFull documentation can be found on the [official site](https://railt.org/).\n\n## Contributing\n\nThank you for considering contributing to the Railt Framework! \nThe contribution guide can be found in the [documentation](https://railt.org/docs/contributions).\n\n## Security Vulnerabilities\n\nIf you discover a security vulnerability within Railt, please send an e-mail to maintainer \nat nesk@xakep.ru. All security vulnerabilities will be promptly addressed.\n\n## License\n\nThe Railt Framework is open-sourced software licensed under \nthe [MIT license](https://opensource.org/licenses/MIT).\n\n## Help \u0026 Community [![Discord](https://img.shields.io/badge/discord-chat-6f4ca5.svg?style=for-the-badge\u0026logo=discord\u0026logoColor=ffffff)](https://discord.gg/ND7SpD4)\n\nJoin our [Discord community](https://discord.gg/ND7SpD4) if you run into issues or have questions. We love talking to you!\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://discord.gg/ND7SpD4\"\u003e\u003cimg src=\"https://habrastorage.org/webt/mh/s4/hg/mhs4hg2eb0roaix7igak0syhcew.png\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\n## Supported By\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.jetbrains.com/\" target=\"_blank\"\u003e\u003cimg src=\"https://phplrt.org/img/thanks/jetbrains.svg\" alt=\"JetBrains\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frailt%2Frailt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frailt%2Frailt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frailt%2Frailt/lists"}