Skip to content

Data API - getData, datové body

CMS se snaží oddělit datový model od aplikace. Nejde o databázi, ale o separaci logiky pro získání a přípravy dat. Zatím není plně odděleno. Nikdy zatím nenastal požadavek oddělení databíze na jiném serveru.

Koncept

V adresáři CONFIG['dataDir'] jsou kontrolery pro získávání dat s veškerou logikou kolem. To znamená, že např. tagy si tímto zavolají datový bod a získají kolekci dat, která již bude připravena pro šablony.

Tento datový bod je volán jak z PHP, tak z front-endu pomocí JS příkazu fetch. Většinou jsou data vrácena v JSON formátu.

Konfigurace

V config/data.yaml definujte adresář pro kontrolery dotazů a případný url odkaz vzdáleného stroje:

dataDir: /app/DATA
dataRemoteUrl:

Router

Ukázka z app/routes/data.php:

const GET_DATA_URL = '/getData';

$cors = (!Ip\isIpAllowed(explode(',', env('ALLOWED_IP', '')))) ? '*' : '*';
Response\cors($cors);

$routes = [
    Route\any($path, DATA_DIR . str_replace(GET_DATA_URL, '', $path) . '.php'),
    Diactoros\text($_SERVER['REQUEST_URI'] . " — not found", 404),
];

$response = Route\matching($routes);

Systém automaticky mapuje URL na soubory dle adresářové struktury. Například: - /getData/EXAMPLES/get-example?param=valueapp/DATA/EXAMPLES/get-example.php

V POST požadavcích je třeba řešit kontrolu metody v samotném kontroleru.

Volání z frontendu (JavaScript)

GET požadavek

fetch('/getData/EXAMPLES/get-example?letter=a&number=1')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

POST požadavek

const url = '/getData/EXAMPLES/post-example?test=72';

const data = {
    name: 'John Doe',
    email: 'johndoe@example.com',
    message: 'Hello, world!'
};

const options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
};

fetch(url, options)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

Volání z PHP skriptů

Zde je komplikovanější. Pokud se jedná o vzdálený server, musí se použít curl, a pokud jde o místní server ve stejné instanci, volají se skripty přímo.

Využívá se core/Data/Data.php a funkce get() a post(). Na vzdáleném serveru pak bude třeba poladit CORS.

Při tomto způsobu volání skriptů přímo z PHP vzniká problém, že data nepřichází v POST a GET požadavku. Zatím tedy definuji u volání require proměnné $_get nebo $_post.

GET

use Petrovo\Data;
use Siler\Encoder\Json;

$query = [
    'content' => PAGE_INFO['content_id'],
    'lang'    => LANG,
];

$output = Data\get('EXAMPLES/get-example?' . http_build_query($query));

// následuje zpracování vrácených dat ve skriptu
$ziskane = Json\decode($output);

POST

use Petrovo\Data;
use Siler\Encoder\Json;

$data = [
    'name' => 'John Doe',
    'phone' => '123456789',
    'city' => 'Prague',
    'lang' => LANG,
];

$output = Data\post('EXAMPLES/post-example', $data);
$ziskane = Json\decode($output);

Tvorba datového endpointu

Datové endpointy jsou umístěny v app/DATA/ a mají přístup k $_get a $_post:

<?php
declare(strict_types=1);

use Petrovo\Data;

// Přístup k parametrům
$id = $_get['id'] ?? null;
$name = $_post['name'] ?? null;

// Logika pro získání dat
$result = [
    'status' => 'success',
    'data' => [
        'id' => $id,
        'name' => $name,
    ]
];

return Data\outputJson($result);

CORS a IP filtrování

Přístup je kontrolován dle CORS nastavení a IP filtrování definovaného v .env:

ALLOWED_IP=127.0.0.1,::1,93.185.102.4
CORS_ORIGINS=

Remote data server

Pokud je v konfiguraci definován dataRemoteUrl, budou se data volat na vzdáleném serveru přes HTTP request. Lokálně budou tagy/kontrolery přijímatelné bez přímého přístupu k databázi.