Non, l’API-PHP de FileMaker n’est pas morte !
Non, l’API-PHP de FileMaker n’est pas morte !
31 mai 2017 - Auteur : - Categories : Blog, FileMaker, Technique - Tag :

Non, l’API-PHP de FileMaker n’est pas morte !

Logo PHP

L’API-PHP de FileMaker est elle en fin de vie ? C’est une question que l’on pourrait se poser depuis qu’une nouvelle technologie est apparue dans FileMaker Server 16 pour nous permettre de partager les données d’une base FileMaker au travers d’un site web: l’API REST. Cependant, bien que cette nouvelle API (encore en version beta) apporte un vrai vent de fraîcheur et offre de belles perspectives d’évolution, elle n’en demeure pas moins limitée pour l’instant et moins adaptée à une architecture web classique où le serveur web occupe un rôle central.

Aussi, la publication XML couplée à l’API-PHP de FileMaker restent encore à ce jour le meilleur moyen pour partager et utiliser une solution directement sur le Web.

Elle souffre malgré tout de certaines lacunes : développée pour être compatible avec PHP 4 à sa sortie (une version encore répandue à l’époque), l’API-PHP originale (téléchargement) n’a quasiment pas évoluée depuis (à part quelques corrections mineures).

Tous ceux qui l’ont utilisée, se rappellent certainement des nombreuses alertes indiquant l’utilisation des méthodes dépréciées dès lors qu’elles étaient exécutées avec une version plus récente de PHP. Bien que ces erreurs aient été corrigées depuis, l’avènement de PHP 7 les a malheureusement remises au goût du jour.

Ce manque d’évolution a rendu son code vétuste, il n’est plus du tout en phase avec les nouvelles méthodes de développement qui ont émergé ces dernières années dans l’univers de PHP, et de fait ce retard d’actualisation rend son intégration compliquée dans tout projet utilisant un framework ou un CMS “moderne”.

Une mise à jour de cette bibliothèque était devenue de plus en plus nécessaire pour assurer sa pérennité. Seulement voilà, bien que PHP ait encore de beaux jours devant lui au vu de ses améliorations régulières et de sa grande popularité, FileMaker a décidé de faire les yeux doux aux technologies plus en vogue actuellement, telles que les frameworks JavaScript. Inutile dès lors d’espérer une quelconque évolution de ce côté-là (La publication XML n’est et ne sera a priori jamais disponible sur FileMaker Cloud par exemple).

Il ne restait donc qu’une seule solution : retrousser ses manches et mettre les mains dans le cambouis afin de prodiguer une petite cure de jouvence à notre chère API-PHP !

Méthodologie

Évidemment, avant de toucher à la moindre ligne de code, il fallait se plonger d’abord, tel un moine cistercien, dans une longue et approfondie étude du code source original, pour comprendre sa structure, son fonctionnement et ses particularités afin de bien saisir l’ampleur du chantier à venir.

Très vite, deux exigences se sont imposées : simplifier au mieux le code source (tout en essayant de l’optimiser), et le moderniser afin de le rendre conforme aux standards de développement actuels, notamment ceux recommandés par le groupe PHP-FIG, dans l’objectif d’assurer une meilleure interopérabilité avec la plupart des frameworks et CMS PHP modernes.

Côté simplification, les changements se sont portés principalement sur une nouvelle stratégie de gestion des erreurs et sur la réécriture d’une partie du code afin de respecter la norme PSR-2 (conventions d’écriture du code source).

La nouvelle gestion d’erreurs consiste à s’affranchir des tests conditionnels ponctuels au bénéfice d’une seule structure générale de test par exceptions, avec un bloc de type “try / catch” englobant les principales instructions de travail (voir un exemple de code plus bas). La méthode originale reste cependant toujours fonctionnelle afin d’assurer une compatibilité descendante.

Cette première étape terminée, il fallait maintenant consolider la compatibilité avec les versions les plus récentes de PHP et en tirer le meilleur parti pour moderniser au maximum le code.

Dès lors, concernant la modernisation du code source, l’ajout des espaces de noms, sur l’ensemble des classes de l’API, couplé à un système “d’auto-chargement”, comme le préconise la spécification PSR-4, se sont imposés, assurant de facto la compatibilité avec les frameworks PHP les plus en vogue du moment.

Cette technique a entraîné un changement en profondeur de la structure des fichiers, sans pour autant modifier le fonctionnement d’origine de l’API, et ce, dans le but de garantir une parfaite compatibilité avec les projets basés sur l’API-PHP de FileMaker originale.

structure des fichiers de l'API-PHP de FileMaker originale

structure des fichiers de l’API-PHP de FileMaker originale

structure des fichiers de l'API-PHP de FileMaker réécrite

structure des fichiers de l’API-PHP de FileMaker réécrite

S’ouvrir au reste du monde

Nous y étions ! l’API-PHP de FileMaker était enfin modernisé ! Ne restait plus alors qu’à l’ouvrir au reste du monde libre !

En effet, depuis quelques années maintenant, les projets PHP se sont structurés autour d’une multitude de bibliothèques tierces, à l’instar de beaucoup d’autres langages tel que java, javascript, …

Afin de simplifier la gestion de ces multiples codes source et d’assurer leur mise à jour sans effort (le code étant maintenu par d’autres développeur), un outil désormais très populaire a été créé : Composer. Celui-ci permet de gérer, à l’aide d’un simple fichier de configuration (json) l’ensemble des bibliothèques tierces d’un projet, en assurant l’installation et la mise à jour.

De toute évidence, notre API se devait de rejoindre la communauté pour achever sa mutation, ce qui nécessita quelques adaptations non sans conséquences : cela a conduit à abandonner le fichier de configuration original de l’API (dans le monde de Composer, une bibliothèque tierce ne doit jamais être modifiée pour garder le bénéfice des mises à jour). Cela implique qu’il est désormais livré avec une configuration « par défaut », qu’il vous appartient de modifier au moment de son instanciation.

Evolutions

Notre nouvelle API fin prête, il nous tardait de l’intégrer dans un projet d’ampleur pour en mesurer son potentiel, ce qui fut rapidement le cas ! Un projet nécessitant l’emploi d’un Framework (yii2) s’étant rapidement présenté.

Ce premier galop d’essai a permis de mettre en lumière certaines lacunes qui n’étaient pas forcément apparues lors de la réécriture, notamment le besoin de faciliter le débogage lors des développements et d’améliorer la communication avec des bibliothèques tierces.

Ainsi, un certain nombre de nouvelles fonctionnalités ont été implémentées au fil de l’eau, dont voici une liste non exhaustive (certaines développées spécifiquement, d’autres issues des fonctions déjà existantes dans l’API-XML de FileMaker, mais non implémentées dans l’API-PHP de FileMaker d’origine) :

  • Choix du format de date en entrée et sortie de l’API ;
  • Prise en charge de la « pagination » lors de l’exécution d’un script ;
  • Définition de globales à l’exécution d’une recherche ;
  • Méthode permettant de récupérer la dernière requête (URL) envoyée au serveur FileMaker  (extrêmement utile pour le debogage en phase de développement);
  • L’objet “Layout” peut désormais renvoyer le nom de la table source (en plus du nom de l’occurrence de table) via la propriété $layout->table, permettant une gestion plus simple des contextes d’exécution ;
  • Méthode permettant la récupération d’une liste de valeurs associée à un champ sur un modèle (les listes peuvent ainsi être renommées sans impact sur votre site web).

Installation et configuration

Voici, en quelques lignes, les principales étapes pour installer et mettre en service cette nouvelle API-PHP de FileMaker.

Il y a deux méthodes d’installation de cette API :

  1. Via la solution “Composer”, en ajoutant "airmoi/filemaker" : "*" à votre fichier de configuration ;
  2. Manuellement en téléchargeant les dernières sources sur le site de GitHub dédié et en installant les fichiers décompressés dans votre projet : Dépot GitHub

Pour le chargement et l’activation de l’API, c’est très simple, il suffit d’inclure le fichier “autoload.php” qui se trouve à la racine du projet (facultatif en cas d’installation via Composer):
require ('/path/to/API/autoload.php');

Vous devez ensuite déclarer la classe à utiliser à l’aide de son espace de nom (l’autoloader se chargeant de trouver automatiquement les fichiers à charger pour assurer le bon fonctionnement de l’API) :
use airmoi\FileMaker\FileMaker;

Le fichier de configuration ayant disparu, deux méthodes sont disponibles pour configurer votre projet :

  1. Utilisation de la méthode PHP de FileMaker : setProperty('name', $value), qui peut servir pour configurer individuellement les différents paramètres du projet ;
  2. Utilisation d’un tableau de paramètres directement à la création de l’objet FileMaker, par exemple :
    new FileMaker($db, $host, $user, $pass, ['dateFormat' => 'd/m/Y'])
    permettant de configurer le projet en une seule instruction.

Voici un code d’exemple illustrant tout ceci :

// Chargement de l'API
require_once ('/path/to/API/autoload.php');

// Définition de l'espace de noms
use airmoi\FileMaker\FileMaker;

// Réglage des options de configuration
$options = [
    'errorHandling' => 'default',
    'locale' => 'fr',
    'prevalidate' => true,
    'dateFormat' => 'd/m/Y',
];

// Création de l'objet FileMaker avec le tableau de paramètres
$fm = new FileMaker($db, $host, $user, $pass, $options);

// Récupération de la liste de tous les modèles et leur affichage
$layouts = $fm->listLayouts();
foreach ($layouts as $layout) {
    echo $layout . '
';
}

Exemples d’utilisation

Gestion des erreurs : l’ancienne méthode

// Réglage des options de configuration
$options = [
   'errorHandling' => 'default',
];

$fm = new FileMaker($db, $host, $user, $pass, $options);

// Récupération d'un modèle et test sur une éventuelle erreur
$layout = $fm->getLayout('sample');
if (FileMaker::isError($layout)) {
    echo "Error: " . $layout->getMessage();
    exit;
}

// Execution de la requete
$result= $fm->newFindAnyCommand('sample')->execute();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

// Récupération d’un enregistrement
$record = $result->getFirstRecord();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

// Modification de l’enregistrement
$record->setField('text_field', str_repeat('a', 51));
$record->commit();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

L’ancien système de gestion d’erreur s’obtient en réglant le paramètre “errorHandling” à la valeur “default”.
Comme on peut le constater, elle vous oblige à répéter vos contrôles pour pratiquement chaque instruction.

Gestion des erreurs : la technique des exceptions

//Le mode de gestion par Exception est configuré par défaut
//il n'est donc pas nécessaire de le préciser dans les options
$fm = new FileMaker($db, $host, $user, $pass);

try {
    // Récupération d'un modèle
    $layout = $fm->getLayout('sample');

    // Récupération d’un enregistrement en 1 ligne 
    $record = $fm->newFindAnyCommand('sample')->execute()->getFirstRecord();

    // Modification de l'enregistrement
    $record->setField('text_field', str_repeat('a', 51));
    $record->commit();
} catch (FileMakerException $e) {
    //Gestion des erreurs ayant pu survenir à n'importe quelle ligne
    printf ('Erreur %d : %s ', $e->getCode(), $e->getMessage());
}

Comme vous pouvez le constater, la gestion d’erreur par exception via le bloc try/catch permet de réduire de façon considérable le nombre de lignes de code.
Toute sa logique peut être centralisée, ce qui simplifie la lecture du code, améliore sa fiabilité et sa maintenance.

Limiter les résultats d’un script

$fm = new FileMaker($db, $host, $user, $pass);
$result = $fm->newPerformScriptCommand('sample', 'create sample data', 50)
    ->setRange(5, 20)
    ->execute();

echo $result->getFetchCount() . '/' . $result->getFoundSetCount();

Désormais, avec cette nouvelle API, on peut demander quel intervalle de données récupérer. Par exemple, on peut demander d’avoir les données correspondant aux enregistrements de 5 à 25. Cela permet d’obtenir une pagination sur un résultat de script, ce qui était impossible auparavant

Définir une globale à l’exécution d’une requête

$fm = new FileMaker($db, $host, $user, $pass);
$result = $fm->newFindCommand('sample')
    ->setGlobal('global_field', date('m/d/Y'))
    ->addFindCriterion('test_field', 1)
    ->execute();

echo $result->getFetchCount() . " enregistrements trouvés.";

Fonctionnalité très pratique, car elle permet désormais de définir une globale au moment de l’exécution d’une requête, ce qui vous permettra par exemple de récupérer, dans vos résultats, des données liées au travers d’une globale.

Conclusion

Comme expliqué au début de l’article, l’API-PHP de FileMaker avait bien besoin d’un sacré coup de jeune pour s’adapter à l’évolution des technologies les plus récentes, notamment concernant l’interaction avec les frameworks PHP modernes.

Cette réécriture a nécessité de nombreuses heures de travail et d’innombrables tests. Le résultat est plus qu’encourageant puisque cette nouvelle version est désormais utilisée quotidiennement en production sur plusieurs projets professionnels gérés par l’équipe de 1-more-thing.

Mais, bien qu’elle soit en l’état assez stable et aboutie pour être utilisée en production, cette réécriture n’est cependant pas encore terminée, bien d’autres améliorations sont en cours et d’autres à prévoir. Si vous souhaitez contribuer à son évolution, vous êtes évidemment les bienvenus : Dépot GitHub.

Un grand merci à tous ceux qui ont participé, directement ou indirectement, à la réalisation de ce projet, et un remerciement tout particulier à Matthias Kühne pour toutes ses contributions.

Ajouter un commentaire