API Platform | Erster Test

API Driven Development ist in aller Munde. Viele neue Frameworks sind zu 100% per API steuerbar oder haben zmd. ALLE Resourcen per API angebunden. Zeit für mich das ganze mal auszuprobieren und was eignet sich da besser als ein Symfony Projekt namens API Platform.

API Platform

REST and GraphQL framework on top of Symfony and React. (Quelle:https://api-platform.com/ ) Geradeaus ein API Framework. Schauen wir uns mal einige Features an die ziemlich cool sind:

User Management

Integriertes Management von Nutzern mit dem bekannten FOS Userbundle

OpenAPI (Swagger) Doku

Automatische Generierung von übersichtlichen API Dokus (hier mehr)

Schicke Doku

weitere Funktionen

Use Case

Was ist ein Test von neuer Software ohne Usecase für ein Test? Kein richtiger. Hello World und Tutorials kann jeder – also was machen? In letzter Zeit habe ich immer öfter Anfragen für Shopware Entwicklungen erhalten – um diese besser zu organisieren möchte ich ein kleines Tool schreiben, dass diese organisiert und an verschiedenen Stellen ausspielt:

Websites: wöchentliche Verfügbarkeit (rot / gelb / grün)

Da ich mehrere Websites hoste und verwalte (unter anderem dieser Blog) – macht es Sinn, dass ganze zentral zu verwalten und über eine API an alle Endpunkte auszuspielen.

Overkill? Ja. Aber ein guter Grund um zu lernen (ITler müssen das bis zum ENDE).

Installation (DOCKER)

Wir laden uns das letzte Stable Release HIER herunter und entpacken es. Danach gehts mit cd in den Ordner:

cd api-platform

Ich werde hier den Weg über Docker nutzen, musste aber dafür auf die neuste Version updaten und danach habe ich docker-compose pull ausgeführt und mit docker-compose up -d gestartet.

Tipp: Wenn Ihr den Port 80 schon für Apache oder NGINX nutzt – stoppt den Service kurz wenn Ihr nur kurz testen wollt oder ändert den Port in den Docker files.

Erste Schritte

Den obigen Screen sehen wir nach der Installation auf localhost – das Adminpanel und die API sind sofort abrufbar und enthalten erstmal nur die Resource Greetings

API Platform Admin Panel

Installation (Symfony Flex)

Da ich schon öfter mit Symfony gearbeitet habe, möchte ich hier auch noch den üblichen Weg zeigen den ich hier auch empfehlen würde, gerade wenn man lokal schon entwickelt und den Port 80 schon nutzt.

composer create-project symfony/skeleton api-platform
cd api-platform
composer req api

Damit wurden bereits alle nötigen PHP Libraries installiert und Ihr müsst nur noch eure DB anbinden und das Model erstellen:

wie üblich in Symfony. Das Model hole ich mir einfach aus der aktuellen DB, das ist einfacher als alle getter und setter selbst zu generieren

Datenbanktabelle
 php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity

und schon haben wir unser Model und müssen hier nur noch unseren API Stuff hinzufügen

Model in Phpstorm

Wenn ich nun meine URL (www.api.de/api/) aufrufe erhalte ich mein Model mit passendem Swagger UI. So far, so simple.

Verfügbarkeits API Endpunkt

Nun sollten bereits alle API Requests laufen (CRUD).

API Admin Panel

Wenn Ihr ein Adminpanel wollt erstellt euch am besten ein eigenes Projekt in einem Subordner mkdir /var/www/api-admin/

Dort dann einfach mit yarn oder npm installieren:

npx create-react-app my-app

oder

yarn create react-app my-app

danach ändert Ihr einfach die URL in App.js und führt yarn start im Root Verzeichnis aus.

API Platform Admin Panel

Schon läuft unsere React App gefüttert von der API

Model anpassen

Da wir in Symfony arbeiten können wir mit dem Doctrine Migrationbundle auch bequem unsere Datenbank über den diff anpassen – denn ich möchte nicht mehr KW und Jahr benutzen, sondern von und bis um größere Projekte zu blocken ohne 10 KW Einträge zu erstellen.

php bin/console  doctrine:migrations:diff
php bin/console doctrine:migrations:execute --up 2019032518502
Doctrine Migration

Authentifizierung

Nun soll das ganze ja nicht nur lokal laufen, also sollten wir unsere API mal schützen. Dafür bietet sich JWT (JSON Web Token), da API Platform dies auch in der Doku empfiehlt. Wir erstellen uns dazu ein User Model mit Symfony.

composer require symfony/security-bundle
composer require maker
php bin/console make:user

Was uns ein Model erstellt welches wir migrieren und danach ein Form für den Login generieren:

php bin/console doctrine:migrations:migrate

achtet darauf das Ihr mind. Mysql 5.7 oder MariaDB 10.2 habt, denn Ihr benötigt JSON als Typ.

php bin/console make:auth

erstellt euch zum Ende dann das Form für den Login.

TIPP: Erstellt euch ein Fixture für euren Nutzer.

<?php

namespace App\DataFixtures;

use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class UserFixture extends Fixture
{
    private $encoder;

    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;
    }

    public function load(ObjectManager $manager)
    {
        $user = new User();
        $user->setEmail('michahobert@gmail.com');
        $encoded = $this->encoder->encodePassword($user, 'test1234');
        $user->setPassword($encoded);
        $user->setRoles(['ROLE_ADMIN']);
        $manager->persist($user);
        $manager->flush();
    }
}

So könnt Ihr bequem euren Benutzer testen ohne vorher eine Registrierung zu bauen.

Ergebnis

Wir haben nun die normalen CRUD Funktionen für unser Verfügbarkeitsmodel.

Model + Operationen

Das ist schon mal eine gute Basis. Nun möchte ich aber auf verschiedenen Seiten diese Verfügbarkeit per KW und Jahr abfragen. Ich müsste mir also einen Custom Endpunkt bauen, dem ich diese beiden Werte gebe oder …

GraphQL

Api Platform bietet auch eine Implementierung von Graphql – einer Query Sprache für APIs. Da ich diese neue QL für die Zukunft der API halte, werde ich darauf in einem getrennten Artikel genauer eingehen.

Errors

Access to fetch at 'http://www.api.de/api' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'null' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Das könnte auftreten, wenn Ihr keinen CORS_ALLOW_ORIGIN Wert eingetragen habt. Dieser sollte in der .env Datei stehen.

CORS_ALLOW_ORIGIN=^https?://admin.api.de(:[0-9]+)?$

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.