{"id":18808469,"url":"https://github.com/devtheorem/phaster","last_synced_at":"2025-04-13T19:32:18.425Z","repository":{"id":57068345,"uuid":"65692159","full_name":"DevTheorem/Phaster","owner":"DevTheorem","description":"A PSR-7 compatible library for easily making CRUD API endpoints","archived":false,"fork":false,"pushed_at":"2024-10-24T03:30:28.000Z","size":121,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-24T20:46:04.120Z","etag":null,"topics":["php","psr-7","rest-api"],"latest_commit_sha":null,"homepage":"","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/DevTheorem.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-15T00:07:30.000Z","updated_at":"2024-10-24T03:30:32.000Z","dependencies_parsed_at":"2023-01-31T21:01:24.494Z","dependency_job_id":"a5f05dff-3691-40b2-90ef-08d7a42cde32","html_url":"https://github.com/DevTheorem/Phaster","commit_stats":{"total_commits":55,"total_committers":2,"mean_commits":27.5,"dds":"0.018181818181818188","last_synced_commit":"f2113b3b4cb4a2ec3ef6bfe65d0076b678cb849d"},"previous_names":["devtheorem/phaster"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTheorem%2FPhaster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTheorem%2FPhaster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTheorem%2FPhaster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTheorem%2FPhaster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DevTheorem","download_url":"https://codeload.github.com/DevTheorem/Phaster/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248768032,"owners_count":21158575,"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":["php","psr-7","rest-api"],"created_at":"2024-11-07T23:08:48.679Z","updated_at":"2025-04-13T19:32:18.419Z","avatar_url":"https://github.com/DevTheorem.png","language":"PHP","readme":"# Phaster\n\nPhaster is a PSR-7 compatible library for easily making CRUD API endpoints.\nIt enables mapping API fields to columns in the database or from a select query,\nand implementing custom validation or row modification logic.\nBuilt on top of [PeachySQL](https://github.com/devtheorem/peachy-sql).\n\n## Installation\n\n`composer require devtheorem/phaster`\n\n## Usage\n\nCreate a class extending `Entities`, and implement the methods to map properties to columns and\ndefine the base SQL query (see example below).\nPass the callable returned by the route handling functions to your Slim or other PSR-7 compatible framework.\n\n```php\n\u003c?php\n\nuse DevTheorem\\Phaster\\{Entities, Prop, QueryOptions};\n\nclass Users extends Entities\n{\n    // Return the table to insert/update/delete/select from.\n    // If not implemented, the class name will be used as the table name.\n    protected function getTableName(): string\n    {\n        return 'users';\n    }\n\n    // Return an array which maps properties to writable column names. Returns an\n    // empty array by default, so no properties will be writable if not implemented.\n    protected function getMap(): array\n    {\n        return [\n            'username' =\u003e 'uname',\n            'firstName' =\u003e 'fname',\n            'lastName' =\u003e 'lname',\n            'isDisabled' =\u003e 'disabled',\n            'role' =\u003e [\n                'id' =\u003e 'role_id',\n            ],\n        ];\n    }\n\n    // Return a list of `Prop` objects, which map properties to readable columns and/or values,\n    // and enable setting a type to cast the column value to, or defining a virtual property\n    // which depends on other columns. See the Prop constructor for the full list of parameters\n    // that can be set. Returns an empty array by default.\n    protected function getSelectProps(): array\n    {\n        return [\n            new Prop('id', col: 'u.user_id'),\n            new Prop('username', col: 'u.uname'),\n            new Prop('firstName', col: 'u.fname'),\n            new Prop('lastName', col: 'u.lname'),\n            new Prop('isDisabled', col: 'u.disabled', type: 'bool'),\n            new Prop('role.id', col: 'u.role_id'),\n            new Prop('role.name', col: 'r.role_name'),\n        ];\n    }\n\n    // Return a SELECT SQL query (without a WHERE clause) in order to join other tables when\n    // selecting data. If not implemented, mapped columns will be selected from the table\n    // returned by getTableName().\n    protected function getBaseQuery(QueryOptions $options): string\n    {\n        return \"SELECT {$options-\u003egetColumns()}\n            FROM users u\n            INNER JOIN roles r ON r.role_id = u.role_id\";\n    }\n\n    // Set the default column/direction for sorting selected results. If not implemented,\n    // results will be sorted by the id property in ascending order by default.\n    protected function getDefaultSort(): array\n    {\n        return ['username' =\u003e 'asc'];\n    }\n}\n```\n\nIf it is necessary to bind parameters in the base query, use `getBaseSelect()` instead:\n\n```php\nuse DevTheorem\\PeachySQL\\QueryBuilder\\SqlParams;\n// ...\nprotected function getBaseSelect(QueryOptions $options): SqlParams\n{\n    $sql = \"WITH num_orders AS (\n                SELECT user_id, COUNT(*) as orders\n                FROM Orders\n                WHERE category_id = ?\n                GROUP BY user_id\n            )\n            SELECT {$options-\u003egetColumns()}\n            FROM Users u\n            INNER JOIN num_orders n ON n.user_id = u.user_id\";\n\n    return new SqlParams($sql, [321]);\n}\n// ...\n```\n\n```php\n\u003c?php\n\nuse My\\DatabaseFactory;\nuse DevTheorem\\Phaster\\{Entities, EntitiesFactory};\n\nclass MyEntitiesFactory implements EntitiesFactory\n{\n    public function createEntities($class): Entities\n    {\n        return new $class(DatabaseFactory::getDb());\n    }\n}\n```\n\n```php\n\u003c?php\n\nuse DevTheorem\\Phaster\\RouteHandler;\n\n$phaster = new RouteHandler(new MyEntitiesFactory());\n\n$app-\u003eget('/users', $phaster-\u003esearch(Users::class));\n$app-\u003eget('/users/{id}', $phaster-\u003egetById(Users::class));\n$app-\u003epost('/users', $phaster-\u003einsert(Users::class));\n$app-\u003eput('/users/{id}', $phaster-\u003eupdate(Users::class));\n$app-\u003epatch('/users/{id}', $phaster-\u003epatch(Users::class));\n$app-\u003edelete('/users/{id}', $phaster-\u003edelete(Users::class));\n```\n\n### Example API request/response\n\nGET `https://example.com/api/users?q[firstName]=Ted\u0026q[isDisabled]=0\u0026fields=id,username,role`\n\n```json\n{\n    \"offset\": 0,\n    \"limit\": 25,\n    \"lastPage\": true,\n    \"data\": [\n        {\n            \"id\": 5,\n            \"username\": \"Teddy01\",\n            \"role\": {\n                \"id\": 1,\n                \"name\": \"Admin\"\n            }\n        },\n        {\n            \"id\": 38,\n            \"username\": \"only_tj\",\n            \"role\": {\n                \"id\": 2,\n                \"name\": \"Standard\"\n            }\n        }\n    ]\n}\n```\n\n## Author\n\nTheodore Brown  \n\u003chttps://theodorejb.me\u003e\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevtheorem%2Fphaster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevtheorem%2Fphaster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevtheorem%2Fphaster/lists"}