{"id":19337903,"url":"https://github.com/2amigos/storage-api-service","last_synced_at":"2025-04-23T01:31:07.851Z","repository":{"id":62485562,"uuid":"175455232","full_name":"2amigos/storage-api-service","owner":"2amigos","description":"A microservice that abstracts asset storage on different providers","archived":false,"fork":false,"pushed_at":"2019-03-21T20:46:21.000Z","size":789,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-02T06:21:38.241Z","etag":null,"topics":["api","flysystem","service","slim","storage"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/2amigos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-13T16:06:35.000Z","updated_at":"2022-12-18T03:00:56.000Z","dependencies_parsed_at":"2022-11-02T09:30:39.486Z","dependency_job_id":null,"html_url":"https://github.com/2amigos/storage-api-service","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2amigos%2Fstorage-api-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2amigos%2Fstorage-api-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2amigos%2Fstorage-api-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2amigos%2Fstorage-api-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/2amigos","download_url":"https://codeload.github.com/2amigos/storage-api-service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250352226,"owners_count":21416458,"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","flysystem","service","slim","storage"],"created_at":"2024-11-10T03:15:46.430Z","updated_at":"2025-04-23T01:31:06.839Z","avatar_url":"https://github.com/2amigos.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Storage service\n\n![Storage API Service](assets/storage-service@2x.jpg)  \n  \nThe Storage service is a microservice that stores files using [league/flysystem]((https://github.com/thephpleague/flysystem)) filesystem abstraction.\n\nIt was built to allow our development teams at [2amigos](https://2amigos.us) to avoid having to configure storage adapters over and over on projects involving a microservices infrastructure. It's a combination of two separate applications, one being Symfony's CI application and the other being an API built with Slim3.    \n  \nThe project uses [Monolog](https://github.com/Seldaek/monolog) for logging, [Fractal](http://fractal.thephpleague.com/) as a serializer, [Tactitian](https://tactician.thephpleague.com/) as a command bus, [Basic access authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) and [Json Web Tokens](https://jwt.io/)   for authentication (this is optional), [Zend filter](https://docs.zendframework.com/zend-filter/) for data filtering and validation, and [Phinx](http://docs.phinx.org/en/latest/) for database migrations.\n  \n[Docker compose](https://docs.docker.com/compose/overview/) and [Postman collection](https://www.getpostman.com/) files are included for easy development, even though `docker` is not strictly necessary for development as you could easily use the built-in PHP server.\n  \nThis project tries to follow DDD principles.\n  \n## Install  \n  \nInstall the latest version using [composer](https://getcomposer.org/).  \n  \n``` bash  \n$ composer create-project --no-interaction --stability=dev 2amigos/storage-service app  \n```  \n  \nIf you are using it from a private repository (using a github url here as an example).  \n  \n``` bash \n$ composer create-project --no-interaction --stability=dev 2amigos/storage-service app --repository-url=https://github.com/2amigos/storage-service  \n```\n\n## Configuration  \n  \nThe project uses environment files to configure secrets. For that reason, you must create a file named `.env` in the root directory of the project. An `.env.example` file has been provided with all required environment values. Modify that file and save it as `.env` in the root directory.  \n  \nBy default, the API application is configured to work under basic authentication processes. It uses an array of users for that purpose but you could easily change that behavior by configuring the `authenticator` option of the [HttpBasicAuthentication middleware(https://github.com/tuupola/slim-basic-auth/blob/3.x/src/HttpBasicAuthentication.php#L43) by creating your own or using one provided by the library. Check the [PdoAuthenticator](https://github.com/tuupola/slim-basic-auth/blob/3.x/src/HttpBasicAuthentication/PdoAuthenticator.php).   \n  \nIf authentication is successful, the action will return a Json Web Token to be used for subsequent calls.   \n  \nAuthentication, or the usage of scopes, are optional. If you don't wish to work with this kind of setup, simply remove the middleware configurations of `HttpBasicAuthentication`, `JwtAuthentication` and `ScopeMiddleware` middlewares.\n\n# Usage  \nCreate a database with the credentials that you used in `.env`   file. Now you can run [Phinx](http://docs.phinx.org/en/latest/commands.html) database migrations with this command: \n\n``` bash  \n./vendor/bin/phinx migrate -e development\n``` \nFor the sake of this example, go to the `public` folder of the app and start the built-in PHP server like this:   \n  \n``` bash  \nphp -S localhost:8080  \n```   \nNow we can access the api at `http://127.0.0.1:8080`.\n## Get a token   \nTo get a token, use the following:  \n  \n``` bash  \n$ curl \"https://127.0.0.1:8080/token\" \\  \n --request POST \\ --include \\ --insecure \\ --header \"Content-Type: application/json\" \\ --data '[\"mail.all\"]' \\ --user test:test  \nHTTP/1.1 201 Created  \nContent-Type: application/json  \n  \n{  \n \"data\": { \"token\": \"XXXXXXXXXX\", \"expires\": 1550271641 }\n }\n ```\n## Storing a document\n\n### Synchronous  \n  \nUsing the `token`, you can now post a request using `application/form-data` to store a document.   \n  \n``` bash   \n$ curl -X POST \\  \n https://127.0.0.1:8080/document/store \\ -H 'Authorization: Bearer YOUR_TOKEN_HERE' \\ -H 'Cache-Control: no-cache' \\ -H 'Content-Type: application/x-www-form-urlencoded' \\ -H 'Postman-Token: 22bf2715-35e4-41ee-a04b-fd8beddcdd62' \\ -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \\ -F name=nameofthedocument \\ -F async=false \\ -F 'document=@/path/to/document/to/attach/41835188_10217308479844850_6484466208170049536_o.jpg'  \n ```\n  \nThe above command will create an email message on the spool directory, configured by default at the `runtime` folder.\n\n### Asynchronous\n  \n#### Sending a document to the queue\n[Enqueue](https://github.com/php-enqueue/fs) is default queue  service and it is configured to use `runtime/queue` directory.\n  \n``` bash   \ncurl -X POST \\  \n https://127.0.0.1:8080/document/store \\ -H 'Authorization: Bearer YOUR_TOKEN_HERE' \\ -H 'Cache-Control: no-cache' \\ -H 'Content-Type: application/x-www-form-urlencoded' \\ -H 'Postman-Token: 22bf2715-35e4-41ee-a04b-fd8beddcdd62' \\ -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \\ -F name=nameofthedocument \\ -F async=true \\ -F 'document=@/path/to/document/to/attach/41835188_10217308479844850_6484466208170049536_o.jpg'  \n ```\n  \nThe above command will create an email message on the spool directory, configured by default at the `runtime` folder.\n\n#### Getting document from the queue and storing it\nWe use [Enqueue Filesystem Transport](https://github.com/php-enqueue/fs) to ease the task of storing documents from the queue as it comes with some handy commands. \n\nThe [php-enqueue/enqueue-bundle](https://github.com/php-enqueue/enqueue-bundle) comes with a set of pretty handy commands. For the full reference of those commands, please go to [its documentation](https://github.com/php-enqueue/enqueue-dev/blob/master/docs/bundle/cli_commands.md).   \n  \nThe one to consume all the documents that go to the queue is `enqueue:consume`:\n`./bin/console enqueue:consume storage --no-interaction -vvv --receive-timeout=60000`\nThe endpoint response will have the document's uuid which you can use in other calls:\n```\n{\n    \"data\": {\n        \"success\": true,\n        \"status\": 3,\n        \"uuid\": \"136b4cdf-736e-488a-a427-b1d1114f376d\"\n    }\n}\n```\n## Pagination\nFor pagination you can use [Pagerfanta](https://github.com/whiteoctober/Pagerfanta) or Cursor. You can use either, it depends on your configuration inside `dependencies.php` - `$container['paginator'] = $container['paginator.pagerfanta'];` If you want to read more about Fractal pagination, you can do it here [Fractal Pagination](https://fractal.thephpleague.com/pagination/)\n\n### Examples:\n\n#### Pagerfanta \n`https://127.0.0.1:8080/documents/list?filter=limit(3|1):order(created_at|desc)`\nIn response you will see something like this:\n```\n\"meta\": {\n        \"pagination\": {\n            \"total\": 17,\n            \"count\": 3,\n            \"per_page\": 3,\n            \"current_page\": 2,\n            \"total_pages\": 6,\n            \"links\": {\n                \"previous\": \"https://127.0.0.1:8080/documents/list?filter=limit(3|1):order(created_at|desc)\",\n                \"next\": \"https://127.0.0.1:8080/documents/list?filter=limit(3|3):order(created_at|desc)\"\n            }\n        }\n    }\n```\nAlso notice that you have next and previous links that you can use.\n\n#### Cursor\n`https://127.0.0.1:8080/documents/list?cursor=limit(3|2)`\nWhere `3` is the limit and `2` is a starting ID that is used as a cursor. You will get something like this:\n```\n\"meta\": {\n        \"cursor\": {\n            \"current\": \"2\",\n            \"prev\": null,\n            \"next\": \"4\",\n            \"count\": 3\n        }\n    }\n```\n## Testing\nFor testing we are using [PHPUnit](https://phpunit.readthedocs.io/en/8.0/)\n\n### Set Up\nTo set up your testing environment, a few steps are needed:\n - create `.env.test` file. You can use `.env.example` and modify it's values to create test file. Value of`APP_ENV` should be `test`\n - create a testing database and use values from your `env.test` file.\n - run a migration to populate the test database `./vendor/bin/phinx migrate -e testing`\n - change env file being used in `./phinx.php` to `.env.test`\n \n### Running tests\nFirst you need to run your local test server. Go to the `public/test/` directory and use this command:\n`php -S localhost:8081`\n\nIf there are no errors, you should see that the test server is listening on the port `8081` - \n`Listening on http://localhost:8081`\n\nFinally run tests with this command:\n`./vendor/bin/phpunit --testdox tests --bootstrap tests/autoload.php`\n\n# Contributing   \nTo contribute, please read our [CONTRIBUTION guidelines](CONTRIBUTING.md).  \n  \n# Credits  \n  \n- [Tuupola slim api skeleton](https://github.com/tuupola/slim-api-skeleton) Thanks for the boilerplate inspiration!  \n- [2amigos](https://2amigos.us)  \n- [All Contributors](../../contributors)  \n  \n# License  \n  \nThe BSD License (BSD). Please see [License File](LICENSE.md) for more information.  \n  \n\u003e [![2amigOS!](https://s.gravatar.com/avatar/55363394d72945ff7ed312556ec041e0?s=80)](http://www.2amigos.us)  \n\u003e \u003ci\u003eBeyond Software\u003c/i\u003e  \n\u003e [www.2amigos.us](http://www.2amigos.us)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2amigos%2Fstorage-api-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F2amigos%2Fstorage-api-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2amigos%2Fstorage-api-service/lists"}