Serveis web amb Laravel
Per poder seguir amb normalitat aquest article cal haver llegit i treballat Laravel.
Contingut
Introducció
Articles previs:
Articles següents:
Perquè Laravel per a serveis web?
No és imprescindible utilitzar Laravel per implementar un servei web. Ens és convenient pels següents motius:
- En el curs de M7 de DAW estem treballant amb aquest framework i ens interessa aprofundir el seu coneixement.
- Integrarem la part del frontend de la nostra web juntament amb la API que farem.
- Laravel facilita l'accés a la base de dades a través del ORM Eloquent, que resulta molt útil.
Primera prova de la API
Anem a implementar una primera prova de API en un projecte Laravel nou. Si et cal, crea'n un.
Totes les funcions que vulguem implementar per al nostre sistema hem de començar per indicar-les al arxiu de rutes:
routes/api.php
De fet, les podríem implementar al mateix arxiu. Quan es compliquin, però, convindrà crear un controlador com vam fer al tutorial de Laravel.
Afegiu el següent codi a routes/api.php:
Route::get('/ping', function(Request $request) {
return "pong! :)";
});
Poseu en marxa el servidor i proveu la funció amb:
$ curl localhost:8000/api/ping pong! :)super@HPi5-07:~/dev/laraveltest1$
Noteu que:
- Encara que hem definit la ruta "/ping", per poder-la cridar hem de fer "/api/ping". Ve predefinit pel Laravel, tot i que no té perquè ser així.
- Ens contesta el què hem posat al RETURN final
- No retorna HTML, retorna un text que pot ser qualsevol cosa
- No hi ha \n final (s'enganxa amb el prompt de la shell)
Headers en la crida curl
Per veure els headers de retorn, podem utilitzar "-i", pot ser molt útil per depurar:
$ curl -i localhost:8000/api/ping
Obtindrem algo com:
HTTP/1.1 200 OK Host: localhost:8000 Date: Wed, 17 Mar 2021 15:13:14 GMT Connection: close X-Powered-By: PHP/7.4.9 Content-Type: text/html; charset=UTF-8 Cache-Control: no-cache, private Date: Wed, 17 Mar 2021 15:13:14 GMT X-RateLimit-Limit: 60 X-RateLimit-Remaining: 59 Access-Control-Allow-Origin: * pong! :)super@HPi5-07:~/dev/laraveltest1$
Autenticació API amb Laravel Sanctum
Des de fa algunes versions Laravel ha incorporat diversos mètodes d'autenticació, entre ells Breeze (bàsic), Fortify (avançat) i Sanctum (API). Aquest darrer és el què ens interessa.
Sanctum té diversos mecanismes, depenent de qui utilitzarà la API (app mòbil, una web externa, etc.). Agafarem l'exemple de la APP MÒBIL.
Consulta aquí la documentació de Laravel Sanctum.
En definitiva, les diferents passes que cal seguir son:
- Instal·lació de Sanctum (install, publish, migrate).
- Anem a la secció per a generar tokens per a mòbils.
- Implementem el mètode d'autenticació mitjançant email i password a l'arxiu api.php. També cal passar-li el device_name que quedarà anotat junt al token.
- Protegim rutes amb ->middleware("auth:sanctum") , per exemple:
Route::middleware('auth:sanctum')->get("/ping", function(Request $request) { // ... }
- Ara simularem la crida per demanar el token (la que posteriorment faríem des d'un mòbil)
curl localhost:8000/api/sanctum/token -X POST -d '[email protected]&password=enric123&device_name=LolaPhone55'
- Crida URL per accedir a la API amb el Header Bearer necessari :
curl localhost:8000/api/ping -H 'Authorization: Bearer lL0a21yHy4MzU4FdV5Cm0xZzd35AJ97acOOnW83t'
Exemples de API: laravel-karaoke
En el projecte karaoke en Laravel, el podeu veure aquí:
- Versió amb el codi a api.php. Es pot fer, però és una solució una mica "guarrilla"
- Versió amb el codi en un controller. Només veiem les rutes, però és raonable que no posem mogollón de codi aquí, sinó al TemaController en aquest cas.
Recordem que per crear un controller amb Laravel ho fem amb (per exemple):
$ php artisan make:controller ApiController
Si mireu TemaController pareu atenció que per poder fer crides com TemaController::fet($id)
, necessitem que siguin funcions estàtiques (static).
Ara, per poder mirar el nº de vots, a routes/api.php tindrem:
Route::get('/nvots/{id}', function(Request $request, $id) {
return TemaController::nvots( $id );
});
Especificacions d'una API
És molt important especificar adequadament una API per tal que la pugui fer servir molta gent.
En l'exemple del karaoke tenim 3 crides, i les especificacions les indiquem amb quadres com els que mostrem a continuació:
- /api/nvots/{tema_id}
- /api/vota/{tema_id}
- /api/fet/{tema_id}
nvots
Al ser una crida GET, els paràmetres han d'anar a la URL. Si fos POST, anirien afegits en el cos de la request:
Veure codi del TemaController@nvots
Request | ||
---|---|---|
GET /api/nvots/{tema_id} | ||
Param | Values | Description |
tema_id | integer | ID del tema del que volem saber el nº de vots que té |
Aquesta response retorna les dades en format JSON, però podria tenir altres formats (XML, plain text):
Response : JSON | ||
---|---|---|
GET /api/nvots/{tema_id} | ||
Param | Values | Description |
status | "OK" / "ERROR" | Estat intern de la consulta/acció |
nvots | integer | Total de vots per al tema |
tema_id | integer | ID del tema consultat |
Per exemple, per testejar-la:
$ curl http://localhost:8000/api/nvots/1 {"status":"OK","tema_id":"1","nvots":1}
Per testejar l'exemple en producció, podeu provar (el -k és important perquè no demani els certificats HTTPS):
$ curl https://jolgorio.tk/api/nvots/1 -k {"status":"OK","tema_id":"1","nvots":2}
vota
Veure codi de TemaController@vota
Request | ||
---|---|---|
GET /api/vota/{tema_id} | ||
Param | Values | Description |
tema_id | integer | ID del tema del que volem saber el nº de vots que té |
Response : JSON | ||
---|---|---|
GET /api/vota/{tema_id} | ||
Param | Values | Description |
status | "OK" / "ERROR" | Estat intern de la consulta/acció |
vot | true / false | Estat actual del nostre vot de la nostra IP |
nvots | integer | Total de vots per al tema |
message | text | Missatge de text amb la descripció de l'error o acció |
fet
Veure codi de TemaController@fet
Request | ||
---|---|---|
GET /api/vota/{tema_id} | ||
Param | Values | Description |
tema_id | integer | ID del tema del que volem saber el nº de vots que té |
Response : JSON | ||
---|---|---|
GET /api/vota/{tema_id} | ||
Param | Values | Description |
status | "OK" / "ERROR" | Estat intern de la consulta/acció |
fet | true / false | Estat actual del tema (fet / no fet) |
message | text | Missatge de text amb la descripció de l'error o acció |