Jednoduché API ve frameworku Slim 4 – č. 3 Struktura API a připojení k databázi
- Jednoduché API ve frameworku Slim 4 – č. 1 Instalace
- Jednoduché API ve frameworku Slim 4 – č. 2 Základní CRUD
- Jednoduché API ve frameworku Slim 4 – č. 3 Struktura API a připojení k databázi
- Jednoduché API ve frameworku Slim 4 – č. 4 Testování funkcionality našeho malého API
- Jednoduché API ve frameworku Slim 4 – č. 5 Vylepšení UserControlleru
- Jednoduché API ve frameworku Slim 4 – č. 6 Přidání Model a Repositories
- Jednoduché API ve frameworku Slim 4 – č. 7 Validace dat
- Jednoduché API ve frameworku Slim 4 – č. 8 Přidáme si do datbáze produkty
Takže API sice máme, ale naplácáno v jednom souboru a s daty napevno vloženými. Dnes si uděláme nějakou reálnější a použitelnější strukturu naší aplikace a zároveň si aplikaci připojíme k databázi.
Přidáme si následující adresáře
/config
– pro konfigurační soubory včetně DB připojení/src
/Controllers
/Models
/Services
/Repositories
V konfiguračním adresáři si vytvoříme soubor database.php, kde si uložíme konfiguraci pro připojení k databázi. Já použiji databázi MySQL a pro připojení použiji PDO v PHP
1 2 3 4 5 6 7 8 9 10 |
return [ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'api', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', ]; |
Super tak pojďme se připojit k databázi, předpokládám, že aplikace se může v budoucno rozrůst o další endpointy, pro připojení k databázi tak raději využijeme Dependency injection aka vkládání závislostí pomocí Containeru. Takže si nejprve nějaký container do naší aplikace přidáme.
1 |
composer require php-di/php-di |
V konfiguračním adresáři si tedy nyní nadefinujeme container a přidáme do něj závislosti soubor dependencies.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php use DI\ContainerBuilder; use Psr\Container\ContainerInterface; use PDO; return function (ContainerBuilder $containerBuilder) { $containerBuilder->addDefinitions([ PDO::class => function (ContainerInterface $c) { $config = require __DIR__ . '/database.php'; $dsn = sprintf( '%s:host=%s;dbname=%s;charset=%s', $config['driver'], $config['host'], $config['database'], $config['charset'] ); return new PDO($dsn, $config['username'], $config['password'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); }, ]); }; |
nyní si také vytvoříme naší databasi a strukturu pomocí
1 2 3 4 5 |
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL UNIQUE ); |
nyní ještě misíme upravit původní index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php use App\Controllers\UserController; use DI\ContainerBuilder; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; use Slim\Exception\HttpNotFoundException; require __DIR__ . '/../vendor/autoload.php'; // Create Container Builder $containerBuilder = new ContainerBuilder(); // Set up dependencies $dependencies = require __DIR__ . '/../config/dependencies.php'; $dependencies($containerBuilder); // Build Container $container = $containerBuilder->build(); // Create App $app = AppFactory::createFromContainer($container); // Middleware pro zpracování JSON $app->addBodyParsingMiddleware(); // Přidání error middleware $app->addErrorMiddleware(true, true, true); /// Routes $app->get('/api/users', [UserController::class, 'getAll']); $app->get('/api/users/{id}', [UserController::class, 'getOne']); $app->post('/api/users', [UserController::class, 'create']); $app->put('/api/users/{id}', [UserController::class, 'update']); $app->delete('/api/users/{id}', [UserController::class, 'delete']); // Spuštění aplikace $app->run(); |
Do souboru jsme místo funkcí pro endpointy našeho API přidali volání UserController třídy, takže celý soubor vypadá již mnohem přehledněji.
A jak tedy pak bude vypadat náš UserController s použitím database?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<?php namespace App\Controllers; use PDO; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Exception\HttpNotFoundException; class UserController { private PDO $db; public function __construct(PDO $db) { $this->db = $db; } public function getAll(Request $request, Response $response): Response { $stmt = $this->db->query('SELECT * FROM users'); $users = $stmt->fetchAll(); $response->getBody()->write(json_encode($users)); return $response ->withHeader('Content-Type', 'application/json') ->withStatus(200); } public function getOne(Request $request, Response $response, array $args): Response { $stmt = $this->db->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$args['id']]); $user = $stmt->fetch(); if (!$user) { throw new HttpNotFoundException($request); } $response->getBody()->write(json_encode($user)); return $response ->withHeader('Content-Type', 'application/json') ->withStatus(200); } public function create(Request $request, Response $response): Response { $data = $request->getParsedBody(); $stmt = $this->db->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); $stmt->execute([ $data['name'] ?? '', $data['email'] ?? '' ]); $user = [ 'id' => $this->db->lastInsertId(), 'name' => $data['name'], 'email' => $data['email'] ]; $response->getBody()->write(json_encode($user)); return $response ->withHeader('Content-Type', 'application/json') ->withStatus(201); } public function update(Request $request, Response $response, array $args): Response { $data = $request->getParsedBody(); // Nejdřív zkontrolujeme, jestli uživatel existuje $checkStmt = $this->db->prepare('SELECT * FROM users WHERE id = ?'); $checkStmt->execute([$args['id']]); if (!$checkStmt->fetch()) { throw new HttpNotFoundException($request); } // Aktualizace uživatele $stmt = $this->db->prepare('UPDATE users SET name = ?, email = ? WHERE id = ?'); $stmt->execute([ $data['name'] ?? '', $data['email'] ?? '', $args['id'] ]); // Načtení aktualizovaného uživatele $stmt = $this->db->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$args['id']]); $user = $stmt->fetch(); $response->getBody()->write(json_encode($user)); return $response ->withHeader('Content-Type', 'application/json') ->withStatus(200); } public function delete(Request $request, Response $response, array $args): Response { // Nejdřív zkontrolujeme, jestli uživatel existuje $checkStmt = $this->db->prepare('SELECT * FROM users WHERE id = ?'); $checkStmt->execute([$args['id']]); if (!$checkStmt->fetch()) { throw new HttpNotFoundException($request); } $stmt = $this->db->prepare('DELETE FROM users WHERE id = ?'); $stmt->execute([$args['id']]); return $response->withStatus(204); } } |