The Storage service is a microservice that stores files using league/flysystem filesystem abstraction.
It was built to allow our development teams at 2amigos 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.
The project uses Monolog for logging, Fractal as a serializer, Tactitian as a command bus, Basic access authentication and Json Web Tokens for authentication (this is optional), Zend filter for data filtering and validation, and Phinx for database migrations.
Docker compose and Postman collection 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.
This project tries to follow DDD principles.
Install the latest version using composer.
$ composer create-project --no-interaction --stability=dev 2amigos/storage-service app
If you are using it from a private repository (using a github url here as an example).
$ composer create-project --no-interaction --stability=dev 2amigos/storage-service app --repository-url=https://github.com/2amigos/storage-service
The 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.
By 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.
If authentication is successful, the action will return a Json Web Token to be used for subsequent calls.
Authentication, 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.
Create a database with the credentials that you used in .env
file. Now you can run Phinx database migrations with this command:
./vendor/bin/phinx migrate -e development
For the sake of this example, go to the public
folder of the app and start the built-in PHP server like this:
php -S localhost:8080
Now we can access the api at http://127.0.0.1:8080
.
To get a token, use the following:
$ curl "https://127.0.0.1:8080/token" \
--request POST \ --include \ --insecure \ --header "Content-Type: application/json" \ --data '["mail.all"]' \ --user test:test
HTTP/1.1 201 Created
Content-Type: application/json
{
"data": { "token": "XXXXXXXXXX", "expires": 1550271641 }
}
Using the token
, you can now post a request using application/form-data
to store a document.
$ curl -X POST \
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'
The above command will create an email message on the spool directory, configured by default at the runtime
folder.
Enqueue is default queue service and it is configured to use runtime/queue
directory.
curl -X POST \
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'
The above command will create an email message on the spool directory, configured by default at the runtime
folder.
We use Enqueue Filesystem Transport to ease the task of storing documents from the queue as it comes with some handy commands.
The php-enqueue/enqueue-bundle comes with a set of pretty handy commands. For the full reference of those commands, please go to its documentation.
The one to consume all the documents that go to the queue is enqueue:consume
:
./bin/console enqueue:consume storage --no-interaction -vvv --receive-timeout=60000
The endpoint response will have the document's uuid which you can use in other calls:
{
"data": {
"success": true,
"status": 3,
"uuid": "136b4cdf-736e-488a-a427-b1d1114f376d"
}
}
For pagination you can use 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://127.0.0.1:8080/documents/list?filter=limit(3|1):order(created_at|desc)
In response you will see something like this:
"meta": {
"pagination": {
"total": 17,
"count": 3,
"per_page": 3,
"current_page": 2,
"total_pages": 6,
"links": {
"previous": "https://127.0.0.1:8080/documents/list?filter=limit(3|1):order(created_at|desc)",
"next": "https://127.0.0.1:8080/documents/list?filter=limit(3|3):order(created_at|desc)"
}
}
}
Also notice that you have next and previous links that you can use.
https://127.0.0.1:8080/documents/list?cursor=limit(3|2)
Where 3
is the limit and 2
is a starting ID that is used as a cursor. You will get something like this:
"meta": {
"cursor": {
"current": "2",
"prev": null,
"next": "4",
"count": 3
}
}
For testing we are using PHPUnit
To set up your testing environment, a few steps are needed:
- create
.env.test
file. You can use.env.example
and modify it's values to create test file. Value ofAPP_ENV
should betest
- create a testing database and use values from your
env.test
file. - run a migration to populate the test database
./vendor/bin/phinx migrate -e testing
- change env file being used in
./phinx.php
to.env.test
First you need to run your local test server. Go to the public/test/
directory and use this command:
php -S localhost:8081
If there are no errors, you should see that the test server is listening on the port 8081
-
Listening on http://localhost:8081
Finally run tests with this command:
./vendor/bin/phpunit --testdox tests --bootstrap tests/autoload.php
To contribute, please read our CONTRIBUTION guidelines.
- Tuupola slim api skeleton Thanks for the boilerplate inspiration!
- 2amigos
- All Contributors
The BSD License (BSD). Please see License File for more information.
Beyond Software
www.2amigos.us