{"id":13990455,"url":"https://github.com/davellanedam/phalcon-micro-rest-api-skeleton","last_synced_at":"2025-04-09T19:22:22.850Z","repository":{"id":80465062,"uuid":"101955563","full_name":"davellanedam/phalcon-micro-rest-api-skeleton","owner":"davellanedam","description":"This is a basic API REST skeleton written on Phalcon PHP. Great For building an MVP for your frontend app (Vue, react, angular, or anything that can consume an API)","archived":false,"fork":false,"pushed_at":"2019-10-02T01:47:50.000Z","size":103,"stargazers_count":57,"open_issues_count":2,"forks_count":18,"subscribers_count":12,"default_branch":"development","last_synced_at":"2025-03-23T21:11:50.325Z","etag":null,"topics":["api","jwt","jwt-authentication","jwt-token","micro","phalcon","phalcon-micro-api","phalcon-skeleton","phalconphp","php","postman","rest","rest-api","skeleton","token"],"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/davellanedam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-08-31T03:33:26.000Z","updated_at":"2024-08-24T02:03:43.000Z","dependencies_parsed_at":"2024-01-18T04:51:10.699Z","dependency_job_id":"78222eec-5def-48a2-a6cc-c02126ab1e5a","html_url":"https://github.com/davellanedam/phalcon-micro-rest-api-skeleton","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davellanedam%2Fphalcon-micro-rest-api-skeleton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davellanedam%2Fphalcon-micro-rest-api-skeleton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davellanedam%2Fphalcon-micro-rest-api-skeleton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davellanedam%2Fphalcon-micro-rest-api-skeleton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davellanedam","download_url":"https://codeload.github.com/davellanedam/phalcon-micro-rest-api-skeleton/tar.gz/refs/heads/development","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248095520,"owners_count":21046862,"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":["api","jwt","jwt-authentication","jwt-token","micro","phalcon","phalcon-micro-api","phalcon-skeleton","phalconphp","php","postman","rest","rest-api","skeleton","token"],"created_at":"2024-08-09T13:02:44.889Z","updated_at":"2025-04-09T19:22:22.814Z","avatar_url":"https://github.com/davellanedam.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# Phalcon Micro REST API Basic Project Skeleton\n\n[![Author](http://img.shields.io/badge/author-@davellanedam-blue.svg?style=flat-square)](https://twitter.com/davellanedam)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/davellanedam/phalcon-micro-rest-api-skeleton/blob/master/LICENSE)\n[![Release](https://img.shields.io/github/release/davellanedam/phalcon-micro-rest-api-skeleton.svg?style=flat-square)](https://github.com/davellanedam/phalcon-micro-rest-api-skeleton/releases)\n\n## Getting started\n\nThis is a basic API REST skeleton written on the **ultra hyper mega fastest framework for PHP [phalcon](https://github.com/phalcon/cphalcon)**. A full-stack PHP framework delivered as a C-extension. Its innovative architecture makes Phalcon the fastest PHP framework ever built!\n\nThis project is created to help other developers create a **basic REST API in an easy way with phalcon**. This basic example shows how powerful and simple phalcon can be. Do you want to contribute? Pull requests are always welcome to show more features of phalcon.\n\n## Features\n\n-   JWT Tokens, provide login with `Authorization` header with value `Basic username:password` where `username:password` **MUST BE ENCODED** with `Base64`.\n-   Make requests with a token after login with `Authorization` header with value `Bearer yourToken` where `yourToken` is the **signed and encrypted token** given in the response from the login process.\n-   Use ACL so you can have roles for users.\n-   Timezone ready: Work UTC time (GMT+0). Responses with iso8601 date/time format.\n-   Pagination ready.\n-   Filters (JSON).\n-   Easy deploy to staging and production environments with rsync.\n-   Internationalization ready. API responses use JSON format to make life easier at the frontend.\n-   Separate database for logs.\n-   User profile.\n-   Users list.\n-   Cities. (Example of use: call cities API, then send name of the city when creating or updating a user.\n-   Integrated tests\n\n## Requirements\n\n-   Apache **2**\n-   PHP **5.6+**\n-   Phalcon **3.2+**\n-   MySQL **5.5+**\n\n## How to install\n\n### Using Git (recommended)\n\n1.  First you need to [install composer](https://getcomposer.org/download/) if you haven´t already.\n2.  Clone the project from github. Change 'myproject' to you project name.\n\n```bash\ngit clone https://github.com/davellanedam/phalcon-micro-api.git ./myproject\n```\n\n### Using manual download ZIP\n\n1.  Download repository\n2.  Uncompress to your desired directory\n\n### Install composer dependencies after installing (Git or manual download)\n\n```bash\ncd myproject\ncomposer install\ncomposer update\n```\n\n### Database Configuration and Security\n\nThere are 3 files in the `/myproject/config` directory, (development, staging and production) each one is meant to be used on different environments to make your life easier on deployment.\n\n1.  Create a MySQL database with your custom name and then import `myproject.sql` (in the `/schemas` directory)\n2.  Create a second MySQL database with your custom name and then import `myproject_log.sql` (in the `/schemas` directory).\n3.  Open `/myproject/config/server.development.php` and setup your DEVELOPMENT (local) database connection credentials\n4.  Open `/myproject/config/server.staging.php` and setup your STAGING (testing server) database connection credentials\n5.  Open `/myproject/config/server.production.php` and setup your PRODUCTION (production server) database connection credentials\n\nThis is the structure of those 3 files, remember to change values for yours.\n\n```php\nreturn [\n    'database' =\u003e [\n        'adapter' =\u003e 'Mysql', /* Possible Values: Mysql, Postgres, Sqlite */\n        'host' =\u003e 'your_ip_or_hostname',\n        'username' =\u003e 'your_db_username',\n        'password' =\u003e 'your_db_password',\n        'dbname' =\u003e 'your_database_schema',\n        'charset' =\u003e 'utf8',\n    ],\n    'log_database' =\u003e [\n        'adapter' =\u003e 'Mysql', /* Possible Values: Mysql, Postgres, Sqlite */\n        'host' =\u003e 'your_ip_or_hostname',\n        'username' =\u003e 'your_db_username',\n        'password' =\u003e 'your_db_password',\n        'dbname' =\u003e 'myproject_log',\n        'charset' =\u003e 'utf8',\n    ],\n    'authentication' =\u003e [\n        'secret' =\u003e 'your secret key to SIGN token', // This will sign the token. (still insecure)\n        'encryption_key' =\u003e 'Your ultra secret key to ENCRYPT the token', // Secure token with an ultra password\n        'expiration_time' =\u003e 86400 * 7, // One week till token expires\n        'iss' =\u003e 'myproject', // Token issuer eg. www.myproject.com\n        'aud' =\u003e 'myproject', // Token audience eg. www.myproject.com\n    ]\n];\n```\n\n### Setting up environments\n\nThe ENV variable is set on an .htaccess file located at `/public/.htaccess` that you must upload **once** to each server you use. Change the environment variable on each server to what you need. To make your life easy this .htaccess file is on the **excluded files list to upload** when you make a deploy. Possible values are: `development`, `staging` and `production`.\n\n```bash\n############################################################\n# Possible values: development, staging, production        #\n# Change value and upload ONCE to your server              #\n# AVOID re-uploading when deployment, things will go crazy #\n############################################################\nSetEnv APPLICATION_ENV \"development\"\n```\n\n## Usage\n\nOnce everything is set up to test API routes either use Postman or any other api testing application. Remember to change the URL of the **provided example Postman JSON file**. Default username/password combination for login is `admin/admin1234`.\n\nIf you use Postman please go to `manage environments` and then create one for each of your servers. Create a new key `authToken` with `token` value (the token you got from the login process), each time you make a request to the API it will send `Authorization` header with the token value in the request, you can check this on the headers of users or cities endpoints in the Postman example.\n\nThis is a REST API, so it works using the following HTTP methods:\n\n-   GET (Read): Gets a list of items, or a single item\n-   POST (Create): Creates an item\n-   PATCH (Update): Updates an item\n-   DELETE: Deletes an item\n\n### Testing\n\nThere are some tests included, to run tests you need to go to the command line and type:\n\n```bash\ncomposer test\n```\n\n### Creating new models\n\nIf you need to add more models to the project there´s an easy way to do it with `phalcondevtools` (If you did `composer install`, you already have this).\nStep into a terminal window and open your project folder, then type the following and you are set!\n\n```bash\nphalcon model --name=your_table_name --schema=your_database --mapcolumn\n```\n\n### Creating new controllers\n\nIf you need to add more controllers to the project there´s an easy way to do it with `phalcondevtools` (If you did `composer install`, you already have this).\nStep into a terminal window and open your project folder, then type the following.\n\n```bash\nphalcon controller --name=your_controller_name_without_the_controller_word\n```\n\nWhen it´s done, it creates your new controller, but if you want to use `ControllerBase.php` functions in your newly created controller you must change the following line in the new controller:\n\n```php\nclass MyNewController extends \\Phalcon\\Mvc\\Controller\n```\n\nto this:\n\n```php\nclass MyNewController extends ControllerBase\n```\n\n### Creating new routes\n\nYou can add more routes to your project by adding them into the `/app.php` file. This is an example of `/users` routes:\n\n```php\n/**\n* Users\n*/\n$users = new MicroCollection();\n$users-\u003esetHandler('UsersController', true);\n$users-\u003esetPrefix('/users');\n// Gets all users\n$users-\u003eget('/', 'index');\n// Creates a new user\n$users-\u003epost('/create', 'create');\n// Gets user based on unique key\n$users-\u003eget('/get/{id}', 'get');\n// Updates user based on unique key\n$users-\u003epatch('/update/{id}', 'update');\n// Changes user password\n$users-\u003epatch('/change-password/{id}', 'changePassword');\n// Adds users routes to $app\n$app-\u003emount($users);\n```\n\nRemember to add the controller (without the controller word) and methods of endpoints to the `/config/acl.php`file. Otherwise you will get this response from the API: `'common.YOUR_USER_ROLE_DOES_NOT_HAVE_THIS_FEATURE',`\n\n```php\n/*\n * RESOURCES\n * for each user, specify the 'controller' and 'method' they have access to ('user_type'=\u003e['controller'=\u003e['method','method','...']],...)\n * */\n$arrResources = [\n    'Guest'=\u003e[\n        'Users'=\u003e['login'],\n    ],\n    'User'=\u003e[\n        'Profile'=\u003e['index','update','changePassword'],\n        'Users'=\u003e['index','create','get','search','update','logout'],\n        'Cities'=\u003e['index','create','get','ajax','update','delete'],\n    ],\n    'Superuser'=\u003e[\n        'Users'=\u003e['changePassword'],\n    ]\n];\n```\n\nAlways keep in mind the following:\n\n```php\n/*\n * ROLES\n * Superuser - can do anything (Guest, User, and own things)\n * User - can do most things (Guest and own things)\n * Guest - Public\n * */\n```\n\n## Internationalization\n\nAPI is designed to response with a JSON, so at the FRONTEND you can use lang files like this:\nPut your language files in 'langs' directory at frontend:\n\n-   `en.json`\n-   `es.json`\n\nExample of language file `en.json` :\n\n```json\n{\n  \"common\": {\n    \"HEADER_AUTHORIZATION_NOT_SENT\": \"Header Authorization not sent\",\n    \"EMPTY_TOKEN_OR_NOT_RECEIVED\": \"Empty token or not received\",\n    \"YOUR_USER_ROLE_DOES_NOT_HAVE_THIS_FEATURE\": \"Your user role does not have this feature\",\n    \"BAD_TOKEN_GET_A_NEW_ONE\": \"Bad token, get a new one\",\n    \"SUCCESSFUL_REQUEST\": \"Succesfull request\",\n    \"CREATED_SUCCESSFULLY\": \"Created successfully\",\n    \"THERE_IS_ALREADY_A_RECORD_WITH_THAT_NAME\": \"There is already a record with that name\",\n    \"UPDATED_SUCCESSFULLY\": \"Updated successfully\",\n    \"DELETED_SUCCESSFULLY\": \"Deleted successfully\",\n    \"THERE_HAS_BEEN_AN_ERROR\": \"There has been an error\",\n    \"INCOMPLETE_DATA_RECEIVED\": \"Incomplete data received\",\n    \"NO_RECORDS\": \"No records\",\n    \"COULD_NOT_BE_CREATED\": \"Could not be created\",\n    \"NOT_FOUND\": \"Not found\",\n    \"COULD_NOT_BE_DELETED\": \"Could not be deleted\",\n    \"COULD_NOT_BE_UPDATED\": \"Could not be updated\"\n  },\n  \"login\": {\n    \"USER_IS_NOT_REGISTERED\": \"User is not registered\",\n    \"USER_BLOCKED\": \"User blocked\",\n    \"USER_UNAUTHORIZED\": \"User unauthorized\",\n    \"WRONG_USER_PASSWORD\": \"Wrong user password\",\n    \"TOO_MANY_FAILED_LOGIN_ATTEMPTS\": \"Too many failed login attempts\"\n  },\n  \"profile\": {\n    \"PROFILE_NOT_FOUND\": \"Profile not found\",\n    \"PROFILE_UPDATED\": \"Profile updated\",\n    \"PROFILE_COULD_NOT_BE_UPDATED\": \"Profile could not be updated\",\n    \"ANOTHER_USER_ALREADY_REGISTERED_WITH_THIS_USERNAME\": \"Another user already registered with this username\"\n  },\n  \"change-password\": {\n    \"PASSWORD_COULD_NOT_BE_UPDATED\": \"Password could not be updated\",\n    \"PASSWORD_SUCCESSFULLY_UPDATED\": \"Password updated successfully\",\n    \"WRONG_CURRENT_PASSWORD\": \"Wrong current password\"\n  }\n}\n```\n\nExample of language file `es.json` :\n\n```json\n{\n  \"common\": {\n    \"HEADER_AUTHORIZATION_NOT_SENT\": \"Cabezote Authorization no enviado\",\n    \"EMPTY_TOKEN_OR_NOT_RECEIVED\": \"Token vacío o no recibido\",\n    \"YOUR_USER_ROLE_DOES_NOT_HAVE_THIS_FEATURE\": \"Tu rol de usuario no tiene esta característica\",\n    \"BAD_TOKEN_GET_A_NEW_ONE\": \"Token errado, solicita uno nuevo\",\n    \"SUCCESSFUL_REQUEST\": \"Solicitud exitosa\",\n    \"CREATED_SUCCESSFULLY\": \"Creado ecitosamente\",\n    \"THERE_IS_ALREADY_A_RECORD_WITH_THAT_NAME\": \"Ya existe un registro con ese nombre\",\n    \"UPDATED_SUCCESSFULLY\": \"Actualizado exitosamente\",\n    \"DELETED_SUCCESSFULLY\": \"Eliminado exitosamente\",\n    \"THERE_HAS_BEEN_AN_ERROR\": \"Ha ocurrido un error\",\n    \"INCOMPLETE_DATA_RECEIVED\": \"Datos incompletos recibidos\",\n    \"NO_RECORDS\": \"No hay registros\",\n    \"COULD_NOT_BE_CREATED\": \"No se pudo crear\",\n    \"NOT_FOUND\": \"No encontrado\",\n    \"COULD_NOT_BE_DELETED\": \"No pudo ser eliminado\",\n    \"COULD_NOT_BE_UPDATED\": \"No pudo ser actualizado\"\n  },\n  \"login\": {\n    \"USER_IS_NOT_REGISTERED\": \"Usuario no está registrado\",\n    \"USER_BLOCKED\": \"Usuario bloqueado\",\n    \"USER_UNAUTHORIZED\": \"Usuario no autorizado\",\n    \"WRONG_USER_PASSWORD\": \"Contraseña de usuario errada\",\n    \"TOO_MANY_FAILED_LOGIN_ATTEMPTS\": \"Demasiados intento de ingreso fallidos\"\n  },\n  \"profile\": {\n    \"PROFILE_NOT_FOUND\": \"Perfil no encontrado\",\n    \"PROFILE_UPDATED\": \"Perfil actualizado\",\n    \"PROFILE_COULD_NOT_BE_UPDATED\": \"Perfil no pudo ser actualizado\",\n    \"ANOTHER_USER_ALREADY_REGISTERED_WITH_THIS_USERNAME\": \"Otro usuario ya se encuentra registrado con este nombre de usuario\"\n  },\n  \"change-password\": {\n    \"PASSWORD_COULD_NOT_BE_UPDATED\": \"Contraseña no pudo ser actualizada\",\n    \"PASSWORD_SUCCESSFULLY_UPDATED\": \"Contraseña actualizada exitosamente\",\n    \"WRONG_CURRENT_PASSWORD\": \"Contraseña actual errada\"\n  }\n}\n```\n\n## Deployment\n\nYou can make a deploy to staging or production servers. It will run a bash file with `rsync` command to sync your project directory to the servers project directory. Step into a terminal window and open your project folder, then type the following.\n\n### Deploy to staging server\n\n```bash\ndeploy-staging.sh\n```\n\n### Deploy to production server\n\n```bash\ndeploy-production.sh\n```\n\n### Do not forget to change variables to yours on each .sh file\n\n```bash\nPROJECT=myproject\nUSER=server_username\nURL=my_staging_server_url\n```\n\n### Excluding files on deploy\n\nYou can exclude files on each deployment environment (`/exclude-production.txt` and `/exclude-staging.txt`), add files you want to be excluded on the corresponding .txt file. Each excluded file or directory must be on a new line. Staging exclusion list example:\n\n```txt\n.git/\n*.DS_Store\n.phalcon/\n.php/\ncache/\n.htaccess\nexclude-staging.txt\nexclude-production.txt\ndeploy-staging.sh\ndeploy-production.sh\nconfig/server.development.php\nconfig/server.production.php\npublic/.htaccess\nschemas/\n```\n\n## Bugs or improvements\n\nFeel free to report any bugs or improvements. Pull requests are always welcome.\n\n## I love this! How can I help\n\nIt´s amazing you feel like that! Send me a tweet \u003chttps://twitter.com/davellanedam\u003e, share this with others, make a pull request or if you feel really thankful you can always buy me a beer! Enjoy!\n\n## License\n\nThis project is open-sourced software licensed under the MIT License. See the LICENSE file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavellanedam%2Fphalcon-micro-rest-api-skeleton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavellanedam%2Fphalcon-micro-rest-api-skeleton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavellanedam%2Fphalcon-micro-rest-api-skeleton/lists"}