Nette jako backend bez Latte

sjiamnocna
Člen | 10
+
+1
-

Zdravíčko,
chci dělat webapps v Reactu, ale rád bych použil Nette jako backend + mám Nginx jako server s možností konfigurace.
Moje znalosti v Nette jsou elementární (basic web s Latte), spíš jsem pracoval čistě s PHP/C, v žádném případě nechci jít do Monga a s Node bych asi taky nic neudělal, takže Nette.

Jak nejlépe vytvořím backend, který přijímá $_POST, manipuluje s daty a vrací JSON, tedy žádné templaty v Latte, jen třeba jeden endpoint na JSON in<->out?

Tedy v Nette by byly Model a Controller… React čístě View

Editoval sjiamnocna (23. 12. 2020 11:57)

David Matějka
Moderator | 6312
+
+12
-

Ahoj,
můžeš sáhnout po nějakém komplexním řešení jako, jako jsou balíčky z rodiny contributte – skeleton API aplikace najdeš tu: https://github.com/…rest-project

ale můžeš na to jít taky víc lightweight, pouze za pomoci Nette a pár utilit.

Za prvé, když budeš psát presentery, tak nebudou dědit od UI\Presenter, ale pouze implementovat IPresenter. Takový jednoduchý Endpoint může vypadat zhruba takto:

<?php declare(strict_types = 1);

namespace App\ApiModule;

use Nette\Application\IPresenter;
use Nette\Application\IResponse;
use Nette\Application\Responses\JsonResponse;
use Nette\Application\Request;

class ListArticlesEndpoint implements IPresenter
{
	public function run(Request $request): IResponse
	{
		return new JsonResponse(['articles' => ....]);
	}

s tím, že to předpokládá následující mapování na presenter:

application:
    mapping:
        Api: App\ApiModule\*\*Endpoint

a vytvoříš normální routu v RouterFactory

$router[] = new Route('/api/article', 'Api:ArticleList');

a bude to fungovat. Ale hodí se pár věcí, které to zjednoduší. Třeba u API se hodí snadno nastavovat response code. Na to se mi nejlépe osvědčilo si udělat ApiResponse, který používám namísto JsonResponse a umožnuje snadné nastavení response code

class ApiResponse implements \Nette\Application\IResponse
{

	/** @var int */
	private $responseCode;

	/** @var JsonResponse */
	private $jsonResponse;


	public function __construct($payload, int $responseCode)
	{
		$this->responseCode = $responseCode;
		$this->jsonResponse = new JsonResponse($payload);
	}


	public function send(IRequest $httpRequest, IResponse $httpResponse): void
	{
		$httpResponse->setCode($this->responseCode);
		$this->jsonResponse->send($httpRequest, $httpResponse);
	}

}

Dále se hodí, abys routy mohl nastavovat jen na konkrétní HTTP metody, tak si vytvořím custom routu:

class ApiRoute implements IRouter
{

	/** @var IRouter */
	private $innerRouter;

	/** @var string */
	private $method;


	public function __construct(string $mask, string $method, $metatada)
	{
		$this->innerRouter = new Route($mask, $metatada);
		$this->method = $method;
	}


	public function match(Http\IRequest $httpRequest)
	{
		if ($httpRequest->getMethod() !== $this->method) {
			return NULL;
		}
		return $this->innerRouter->match($httpRequest);
	}


	public function constructUrl(Request $appRequest, Http\Url $refUrl)
	{
		return NULL;
	}
}

tu můžu v router factory používat namísto nette nativní Routy:

$router[] = new ApiRoute('/api/article', 'GET', 'Api:ArticleList');

a potom, až napíšeš pár endpointů, tak zjistíš, že by se asi hodil nějaký base Endpoint, podobný UI\Presenteru pro webové aplikace, ve kterém třeba budeš řešit dekódování vstupního Jsonu atd. ale to už zvládneš ;)

sjiamnocna
Člen | 10
+
0
-

Děkuju za podrobné instrukce, snad to i někdy pochopím a realizuju :D

Určitě chci mít nějaký root, který přijímá a překládá požadavky a deleguje práci, to žádná.
Jen bych se rád naučil „Nette way of doing things…“ a zároveň co nejvíc lightweight.

chemix
Nette Core | 1157
+
+1
-

Zatim neni zadna officialni „Nette way of doing things…“ … ale to co tu poslal David tak je lightweight a pro tvuj in→ out ta snadna cesta bez velkych zavislosti 3. stran.