Framework de microservice PHP

Bonjour à tous, je m'appelle Alex. Je veux vous présenter mon framework PHP pour créer des microservices. Il est né de mon expérience d'il y a trois ans, qui est ensuite devenue un projet pour animaux de compagnie, et plus tard dans ce cadre, j'ai créé plusieurs projets de production.

Quand j'ai commencé à le faire, j'ai décidé de prendre une décision qui:

  • peut être facilement intégré dans des projets existants;
  • vous pouvez rapidement créer au moins quelque chose qui fonctionne;
  • les designs les plus concis et expressifs;
  • sagement utilisé les capacités du PHP moderne.

Alors par où commencer? Bien sûr de la source! Vous pouvez les regarder sur github

Eh bien, afin de ne pas entrer dans de longs arguments, commençons tout de suite avec un exemple de travail.
Tout d'abord, nous avons besoin de .htaccess, dans lequel nous allons configurer plusieurs règles:

# use mod_rewrite for pretty URL support RewriteEngine on RewriteRule ^([a-z0-9A-Z_\/\.\-\@%\ :,]+)/?(.*)$ index.php?r=$1&%{QUERY_STRING} [L] RewriteRule ^/?(.*)$ index.php?r=index&%{QUERY_STRING} [L] 

Ensuite, vous pouvez créer votre premier service. Dans ce document, nous créerons un point de terminaison qui traitera la méthode GET et renverra un message indiquant que tout va bien. Une sorte de bilan de santé.
Pour commencer, nous devons connecter notre framework:

 require_once ('vendor/service/service.php'); 

Ensuite, nous créons une classe pour le microservice:

 class TodoService extends ServiceBase implements ServiceBaseLogicInterface { /* class body */ } 

Nous avons ici:

  • ServiceBase est une classe de service de base avec les fonctionnalités les plus basiques et les plus utilitaires;
  • ServiceBaseLogicInterface est l'interface que toute classe doit implémenter si elle souhaite fournir des gestionnaires de point de terminaison. Bien que cette interface n'impose aucune exigence particulière à votre classe. Juste fait pour une frappe plus stricte.

Ensuite, nous obtenons le premier gestionnaire de point de terminaison:

 public function action_ping() { return ('I am alive!'); } 

Ensuite, nous lançons notre premier microservice:

 Service::start('TodoService'); 

En mettant tout cela ensemble, nous obtenons:

 /** * Service class */ class TodoService extends ServiceBase implements ServiceBaseLogicInterface { /** * First endpoint */ public function action_ping() { return ('I am alive!'); } } Service::start('TodoService'); 

Une question raisonnable peut se poser - et à quelle URL cette fonctionnalité est-elle disponible? Le fait est qu'en définissant une méthode avec le préfixe action_ <name-part>, vous avez indiqué clairement au service qu'il s'agit d'un gestionnaire d'URL <name-part>, c'est-à-dire dans notre cas, ce sera quelque chose comme localhost / ping
Le trait de soulignement dans le nom de la méthode devient -. C'est-à-dire La méthode action_hello_world sera disponible sur localhost / hello-world

Nous avons continué.

Tout comme pour les applications GUI, il serait bien d'utiliser MVC (ou un autre modèle avec séparation du composant visuel et de la logique), ainsi que dans le microservice. Les choses qui peuvent être brisées sont mieux brisées.

C'est-à-dire dans notre cas, laissez la classe de service continuer à exécuter des fonctions utilitaires pour initialiser le service et lancer le gestionnaire souhaité, et placez la logique dans une classe distincte. Pour ce faire, nous modifions notre code comme suit:

 class TodoLogic extends ServiceBaseLogic { /** * First endpoint */ public function action_ping() { return ('I am alive!'); } } class TodoService extends ServiceBase { } Service::start('TodoService', 'TodoLogic'); 

Ensuite, nous avons eu une classe avec la logique:

 class TodoLogic extends ServiceBaseLogic 

Hérité de la classe de base ServiceBaseLogic (il a un minimum de fonctions, nous allons donc l'examiner en détail plus tard).

La classe TodoService a cessé d'implémenter l'interface ServiceBaseLogicInterface (en fait, elle n'a pas disparu, elle vient tout juste d'être mise en œuvre par la classe ServiceBaseLogic).

Après avoir supprimé la logique, la classe TodoService s'est avérée vide et peut être supprimée en toute sécurité, ce qui réduit encore plus le code:

 class TodoLogic extends ServiceBaseLogic { /** * First endpoint */ public function action_ping() { return ('I am alive!'); } } Service::start('ServiceBase', 'TodoLogic'); 

Ici, la classe ServiceBase est responsable du démarrage du service, pas du nôtre.

Nous avons conduit encore plus loin.

Dans le processus d'utilisation de mon framework, à un certain moment, des classes avec une logique de taille monstrueuse ont commencé à se révéler. Ce qui a irrité mon sens de la beauté d'une part, d'autre part, Sonar était indigné, d'autre part, le concept de diviser les méthodes en méthodes de lecture et méthodes d'écriture (voir CQRS) n'était pas clair sur la façon de le mettre en œuvre.

Par conséquent, à un certain moment, il est devenu possible de regrouper les gestionnaires de point de terminaison selon l'un ou l'autre attribut selon différentes classes de logique et, si nécessaire, de les exécuter au sein du même service ou de les répartir sans peine entre différents.

C'est-à-dire Vous pouvez soit faire toute la logique CRUD dans un seul service. Et il peut être divisé en deux services:

  • l'un fournit des méthodes de lecture;
  • et l'autre fournit des méthodes de modification des données.

Ajoutons maintenant une méthode de création d'entité et une méthode de récupération de liste d'entités à notre exemple:

 class TodoSystemLogic extends ServiceBaseLogic { public function action_ping() { return ('I am alive!'); } } /** * Read logic implementation */ class TodoReadLogic extends ServiceBaseLogic { public function action_list() { return ('List!'); } } /** * Write logic implementation */ class TodoWriteLogic extends ServiceBaseLogic { public function action_create() { return ('Done!'); } } Service::start('ServiceBase', [ 'TodoSystemLogic', 'TodoReadLogic', 'TodoWriteLogic' ]); 

Nous n'aborderons que les changements:

  • les classes TodoSystemLogic (méthodes système), TodoReadLogic (méthodes de lecture), TodoWriteLogic (méthodes d'écriture) sont apparues;
  • lors du démarrage du service, nous transférons non pas une classe avec la logique, mais plusieurs.

C'est tout pour aujourd'hui. Je vais discuter d'autres fonctionnalités du cadre dans les articles suivants. Il y en a beaucoup. En attendant, vous pouvez voir par vous-même ce qui est intéressant là-bas .

Source: https://habr.com/ru/post/fr480828/


All Articles