Kako da kreirate REST API u PHP-u
API-ji (Application Programming Interfaces) u savremenom razvoju web aplikacija predstavljaju najvažniju tačku razmene podataka i logike između različitih sistema. Zato ćemo vam u ovom tekstu pokazati vam kako da izgradite REST API u PHP-u uz tri važna alata: Slim kao lagani mikroframework, Laravel kao sveobuhvatni framework i Swagger (OpenAPI) za standardizovanu dokumentaciju.
Kao što verovatno već znate, REST (Representational State Transfer) postao je dominantni stil izgradnje API-ja upravo zahvaljujući tome što za manipulaciju resursima koristi jasan set HTTP metoda (GET, POST, PUT, DELETE) .
Ukoliko želite da detaljnije upoznate REST API koncept, predlažemo da pročitate naš REST API vodič za početnike.
Slim – lagani mikroframework
Slim je razvijen sa namerom da obezbedi samo osnovni mehanizam za rutiranje i obradu HTTP zahteva, oslanjajući se na PSR-7 standard za klasu Request i Response. Umesto gomile unapred definisanih biblioteka, Slim očekuje da dodate sopstveni kod ili pakete za rad sa bazom, validacijom ili logovanjem. Takav minimalistički pristup čini ga veoma pogodnim za mikroservise ili prototipove, jer je kod manji i brži, a pritom vi sami odlučujete koje komponente ćete da uvedete.
Zašto baš PSR-7 i PSR-15 u Slim-u?
PSR-7 definiše strukturu HTTP zahteva i odgovora kao objekte, dok PSR-15 definiše način na koji se middleware slojevi nadovezuju jedan na drugi. Pošto Slim poštuje ove standarde, veoma jednostavno možete ubacivati ili menjati module za logovanje, autentifikaciju ili bilo šta drugo, bez brige da ćete pokvariti osnovnu logiku aplikacije.
Sama osnova Slim-a počiva na AppFactory klasi, koja kreira aplikaciju, i sistemu rutiranja gde za svaku rutu možete definisati funkcionisanje unutar closure-a ili posebne klase. Primer minimalnog projekta kreće od kreiranja novog direktorijuma i instalacije:
mkdir php-api
cd php-api
composer init --require="slim/slim:^4.0" -n
composer install
Unutar public/index.php možete videti kako se PSR-7 objekti prosleđuju:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use App\User;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();
Ova mini aplikacija već prikazuje kako Slim radi ispod haube. Kada stigne HTTP zahtev sa putanjom /hello/{name}, Slim ruter detektuje rutu, izvlači vrednost {name} i prosleđuje je kroz $args. Sva dalja logika, poput povezivanja sa bazom ili upisa logova, vaša je odluka.
U suštini, Slim je onoliko sposoban koliko vi poželite da bude, jer sve dodatne funkcionalnosti možete da integrišete preko Composer paketa ili sopstvenih klasa.
Ukoliko želite da kreirate RESTful API, možete to učiniti definisanjem GET, POST, PUT i DELETE ruta za rad sa različitim resursima. U primeru s modelom User, klasa sadrži statički niz korisnika i metode za getById i create, a rute u index.php pozivaju te metode, uz manipulaciju JSON podacima. Slim pritom ne zna ni za kakvu bazu, ORM ili šablon – sve je u vašim rukama.
Kratka napomena o greškama i logovanju u Slim-u
Slim ne obezbeđuje detaljan sistem za obradu grešaka i logove. U praksi se često koristi Monolog ili neki drugi PSR-3 kompatibilan logger, dok se za globalnu obradu grešaka (npr. prilagođena stranica za 404 ili hvatanje izuzetaka) oslanjate na middleware sloj ili definisane error handler funkcije. Ovo ostavlja programeru punu kontrolu, ali zahteva ručnu integraciju.
Laravel – full PHP framework
Ako je Slim sušta minimalistička suprotnost, Laravel predstavlja sveobuhvatno rešenje koje ima gotove odgovore na mnoga pitanja: kako organizovati bazu i migracije, kako strukturirati kontrolere i modele, kako validirati ili autentifikovati zahteve.
Laravel dolazi sa Eloquent ORM-om, sistemom migracija, kontrolerima, validacijom, ugrađenim alatima za keširanje, pa čak i redove zadataka i event-ove. Time nudi pristup koji značajno ubrzava razvoj, naročito kada aplikacija postane kompleksna i zahteva više od pukog rutiranja i vraćanja JSON-a.
Laravel projekat se obično kreira komandom:
composer create-project laravel/laravel laravel-api
cd laravel-api
php artisan serve
Tu dobijate čitav direktorijumski sistem, gde app/Models može sadržati modele (koji koriste Eloquent ORM), app/Http/Controllers kontrolere i routes/api.php posebnu datoteku za definisanje ruta prema REST principu. Sve je povezano kontejnerom usluga (Service Container) i mehanizmom binding-a, tako da rad s bazom, transakcijama ili validacijom ne morate sami da izmišljate.
Model “User” kreirate alatom:
php artisan make:model User -m
Fajl migracije zatim opisuje kako izgleda tabela u bazi:
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
Pokretanjem php artisan migrate kreirate realnu tabelu u bazi, a php artisan db:seed vam pomaže da naselite podatke. Model “User” postaje klasa zasnovana na Eloquentu, čime User::all() vraća sve korisnike, a User::find($id) jednog korisnika. Da biste sve to izložili kao REST API, definišete kontroler:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
return response()->json(User::all());
}
public function show($id)
{
$user = User::find($id);
if ($user) {
return response()->json($user);
}
return response()->json(['error' => 'User not found'], 404);
}
public function store(Request $request)
{
$request->validate(['name' => 'required|string']);
$user = User::create($request->only('name'));
return response()->json($user, 201);
}
}
Dok u routes/api.php postavljate:
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::post('/users', [UserController::class, 'store']);
Laravel tu nije fokusiran samo na to kako definisati rutu već i na čitav niz dodatnih mehanizama: sistem migracija, Eloquent ORM, validaciju, middleware-e za autentifikaciju i logovanje. Rezultat je brži razvoj, naročito ako vaš API zahteva kompleksniji rad s bazom ili planirate da vremenom uvodite različite module i funkcionalnosti.
Ukoliko želite da saznate više o ovom sjajnom framework-u, predlažemo da obavezno pročitate neke od tekstova na temu Laravela koje smo pisali na našem blogu.
Konfiguracija okruženja i logova u Laravel-u
Pored toga što nudi gotove alate za rad s bazom, Laravel koristi .env fajlove da razdvoji podešavanja za razvoj, staging i produkciju.
U produkcionom modu možete keširati konfiguracije i rute, čime se ubrzava odziv aplikacije. Greške i logovi se prema podrazumevanim podešavanjima beleže u storage/logs/laravel.log (što koristi PSR-3 kompatibilni logger), a za proizvodno okruženje treba podesiti APP_DEBUG=false kako bi se korisniku skrivale detaljne informacije o izuzetku.
Swagger (OpenAPI) – opis i dokumentacija
Dok su Slim i Laravel usmereni na to kako da kreirate API, Swagger (OpenAPI) doprinosi standardizovanom opisu kako API izgleda i kako bi klijenti trebalo da ga pozivaju. Ideja je da se na jednom mestu čuvaju informacije o rutama, parametrima, tipu sadržaja i mogućim odgovorima, a da se potom iz te specifikacije generiše čitljiva, interaktivna dokumentacija.
Swagger je evoluirao u OpenAPI specifikaciju i postao široko prihvaćen. U PHP projektima se tipično koristi swagger-php biblioteka koja traži anotacije u kodu i pretvara ih u JSON fajl swagger.json. Taj fajl se onda prikazuje putem Swagger UI (recimo, na https://editor.swagger.io/) kao vizuelno prijatan i klijentima razumljiv opis API-ja.
Ako timovi sa različitim tehnologijama (mobilni, frontend, spoljni partneri) treba da rade sa vašim API-jem, Swagger (OpenAPI) smanjuje nesporazume i omogućava jasnu dokumentaciju. Ovo je naročito korisno kad API raste ili menja formu, jer svi dobijaju ažuriranu sliku kako treba da pošalju zahtev i kakav odgovor mogu da očekuju.
Komanda composer require zircote/swagger-php ubacuje potrebne alatke, a vi unutar svog projekta možete kreirati fajl app/openapi.php pun anotacija:
<?php
use OpenApi\Annotations as OA;
/**
* @OA\Info(
* title="My PHP API",
* version="1.0",
* description="REST API za korisnike"
* )
*/
/**
* @OA\Get(
* path="/api/users",
* summary="Lista korisnika",
* @OA\Response(response=200, description="Uspešno")
* )
*/
Pokretanjem vendor/bin/openapi app -o public/swagger.json dobijate fajl u JSON formatu, koji postaje nacrt vašeg API-ja. Ovakva dokumentacija je od ogromne pomoći ako na API-ju radi veći tim ili ako klijenti iz drugih programskih jezika žele da se priključe bez lutanja.
Zaključak
U ovom tekstu smo predstavili dva glavna pristupa izgradnji REST API-ja u PHP-u i način na koji ih možete dokumentovati pomoću Swagger-a.
Prvi pristup, kroz Slim, nudi vam maksimalnu kontrolu i brzinu za manje projekte, prototipove i mikroservise, jer se sami bavite gotovo svim sporednim aspektima, od baze podataka do validacije.
Drugi pristup, kroz Laravel, uključuje snažan skup alata i konvencija, pa se često koristi u većim timovima i zahtevnijim projektima, gde gotova rešenja i integrisani ORM značajno ubrzavaju rad.
Uz Swagger (OpenAPI), bez obzira na to da li ste odabrali Slim ili Laravel, možete kreirati univerzalan opis svog API-ja u kojem su jasno definisani parametri, očekivani formati, HTTP metode i odgovori. Time se olakšava saradnja različitih timova i održavanje same aplikacije, a krajnjim korisnicima API-ja pruža se jasan uvid u raspoložive rute i načine na koje mogu da ih koriste.
Razumevanjem ova tri alata, otvara vam se mogućnost da svoju PHP aplikaciju postavite na stabilne osnove, sa jasnim, održivim i dobro dokumentovanim interfejsom ka svim klijentima koji podatke treba da uzimaju ili šalju. Sada je na vama da izaberete pristup koji najbolje odgovara vašem konkretnom problemu ili veličini tima i projekta.
