A small example of how an API could be written in Symfony. This project allow a user to receive/add/update/delete cars.
All output is standardized so that it is easy to parse in any language on any environment.
It now also features an implementation of JSON Web Tokens for authenticating users.
- JWT Authentication
- Data retrieval
- Data manipulation
There are two SSH keys in /var/jwt
. These encrypt all the tokens we send and read. I have committed
them for the ease of use and testing, but remember to ALWAYS generate new ones and keep them secret
in your own applications. See the official documentation on how to do this.
- Register user (manually or through fixture. May add easier registration on request)
- User retrieves token
- User consumes API
- Token times out after 10 minutes
# POST retrieve a token
symfony.app/api/token
# GET car
symfony.app/car
# GET car by id
symfony.app/car/{id}
# POST new car
symfony.app/car
# PATCH update car
symfony.app/car/{id}
# DELETE remove car
symfony.app/car/{id}
- PHP >= 7.1
- Composer
- MySQL >= 5.5
- Clone this repo
- Run
composer install
- Run
php bin/console doc:mig:mig
- Run
php bin/console doc:fixtures:load
- Run
php bin/console doc:mig:mig --env=test
- Run
composer test
For more information which tests are run, please refer to the "test"
section of composer.json
.
You can run the given tests separately, i.e. composer behat
or composer phpunit
All error messages have the same format, so they can be easily parsed in any language:
{
"error": {
"code": 401,
"message": "Not privileged to request the resource."
}
}
$ curl --request POST \
--url http://symfony.app/api/token \
--header 'password: unsafepassword' \
--header 'username: admin'
{
"token": "eyJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNDg0NTgyNTc4LCJpYXQiOjE0ODQ1ODE5Nzh9.t31C2jYVHWybZ2szEFwkGEzspYFyg9BlTyolnYtznnm8eFPIZI00hZPYCPFX2Ka7-gBFb3keM_2WVhfXKvreQpaFzge2HQ1lfMgVBCCUsxoiESUo6qCkna0Vb6ttv1qLyBRAqui_ijjANaAqEgO648vnIP0BMOYkjzw9-jNJNRQ25Bv4Y7bc_LGcGJQc2wGlg5sxWqMYhHwwCncBNPpdwTj9e9WULGBv0U1Hc_8I5eCrQFrCJGeQaKnEiy1GKXdRCSqwfCqEDrbXhgkBGygUbPGAYrfU8SnrtxFRI_EN92PByo2rjpy_M5gL-Md6czN5xDSxJHmswValR-I1ga1WkqEf194erD7KJmRRXUpz1HwNDWPDm1RJfzVgj0vTlW7kCKdLqGkkvaVnPuToxLhAPnp-kfdFkprtND0J8CajdiKaYVia4DwOjK4w_lbnfLMzZp6s6o7eKQ4h7_vkZAGu_DA0f6fVOuGQc5cqef_1oMqbKKrhVWL4xMg9wovpkAm_AF-iii-cjaXejArKzZ_4sKku5fc7BleSIHH0sXXLWlE_bI6ftc3AAxTl1buIOwpqrKDwlU_YfO8d9YkuZCRG-I0B8Nu0hfW6qh3jwIaqlqaAP6ZqAfAk8Sd6cQw8eqSqjhFjtSKA2J-DYn4lP2DC-0-_6ydj8sl3pB-DV7MEVVI"
}
$ curl --request GET \
--url http://symfony.app/car \
--header 'Authorization: Bearer {token}'
[
{
"id": 1,
"brand": "Ford",
"name": "Mustang",
"year": 1972
},
{
"id": 2,
"brand": "Toyota",
"name": "Corolla",
"year": 1983
},
]
$ curl --request GET \
--url http://symfony.app/car/{id} \
--header 'Authorization: Bearer {token}'
{
"id": 1,
"brand": "Ford",
"name": "Mustang",
"year": 1972
}
$ curl --request POST \
--url http://symfony.app/car \
--header 'content-type: application/json' \
--header 'Authorization: Bearer {token}'
--data '{
"brand": "Ford",
"name": "Mustang",
"year": 1972
}'
{
"id": 1,
"brand": "Ford",
"name": "Mustang",
"year": 1972
}
$ curl --request PATCH \
--url http://symfony.app/car/{id} \
--header 'content-type: application/json' \
--header 'Authorization: Bearer {token} \
--data '{
"year": 2016
}'
{
"id": 1,
"brand": "Ford",
"name": "Mustang",
"year": 2016
}
$ curl --request DELETE \
--url http://symfony.app/car/{id} \
--header 'Authorization: Bearer {token}
{
"message": "Car deleted"
}