J'essaie de renvoyer un objet JSON à partir de l'un de mes modèles REST, quelque chose comme ceci:
{
"settings": {
"set1" : 2,
"set2" : "key1"
},
"extra": {
"e1'" : {
"e2'": true
}
}
}
Cependant, ce qui semble banal n'est pas si simple à mettre en œuvre. Le problème est que je ne sais pas quel doit être le type de retour dans l'interface et le modèle.
<?php
namespace AppFactory\Core\Api;
/**
* @api
*/
interface SettingsInterface
{
/**
* @return object
*/
public function get();
}
La classe d'objets retournera
{
"message": "Class object does not exist",
lors de l'appel de l'API. Les types primitifs disponibles int, nombre et tableau ne fonctionneront pas pour moi. Je ne veux pas créer de classe pour chaque type complexe qui revient également. Comment puis-je faire ceci?
Merci.
magento2
webapi
magento2-api
Yehia A.Salam
la source
la source
Réponses:
Je suppose que
AppFactory\Core\Api\SettingInterface::get()
c'est un point de terminaison REST. Dans ce cas, dans les commentaires phpdoc, vous devez définir ce que cela renverra. Le gestionnaire Magento REST prendra cette valeur et la traitera pour supprimer toutes les données inutiles. Ce qui reste sera encodé en JSON, donc en javascript, vous pouvez le récupérer en tant que hachage JS déjà correct et non en chaîne encodée en json.L'astuce à propos de ces points de terminaison est que vous devez définir très précisément ce que vous retournerez. Magento ne sera pas en mesure de traiter quelque chose d'aussi général que "array" où vous définirez ce que vous voulez.
Dans votre cas, afin de ne pas essayer de jouer avec un tableau de chaînes, il sera plus facile de créer une interface que votre endpoint retournera.
Maintenant, lorsque vous retournez une instance d'un objet implémentant cette interface, Magento lira ses phpdocs et traitera leurs valeurs de retour. Maintenant, créez un fichier
AppFactory\Core\Api\Data\SettingsInterface
comme suitMaintenant, lorsque vous créez une classe réelle qui implémentera ces 2 méthodes get et que vous la retournerez,
AppFactory\Core\Api\SettingsInterface::get()
magento renverra quelque chose commeSi vous voulez un autre niveau, vous devez créer une autre interface qui gardera la
settings
structure et l'ajoutera comme valeur de retour pourAppFactory\Core\Api\Data\SettingsInterface::getSettings()
.Si vous avez besoin d'avoir quelque chose qui sera dynamique et que vous ne voulez pas ou ne pouvez pas préparer cette interface de structure, vous pouvez essayer de définir une chaîne codée json et de la placer
@return string
pour l'un des champs. De cette façon, cependant, vous devrez vous assurer de décoder manuellement cette chaîne après avoir reçu la réponse, car votre réponse ressemblera à ceci:et pour l'utiliser,
response.extra.test
vous devrez d'abord le faireresponse.extra = JSON.parse(response.extra);
manuellementla source
AppFactory\Core\Api\DataSettingsInterface
. Si cela fonctionne, il vous suffit de faire le premier niveau de la réponse.J'ai également fait face à ce problème, et comme alternative à la solution proposée par @Zefiryn, j'ai travaillé autour de lui en enfermant les données de retour dans un tableau (ou deux). Veuillez considérer l'exemple ci-dessous.
En raison de la façon dont Magento 2 autorise les tableaux de contenu mixte en tant que valeurs de retour, des structures de données plus complexes peuvent être intégrées dans d'autres tableaux. L'exemple ci-dessus donne la réponse JSON suivante (tronquée pour plus de lisibilité).
L'enfermer dans une seule couche supprime les clés du tableau, et sans l'enfermer dans aucun tableau entraîne une erreur.
Naturellement, rien de tout cela n'est idéal, mais cette approche me permet de contrôler la cohérence de la structure de données retournée dans une certaine mesure (la structure et les types de données attendus). Si vous contrôlez également l'écriture d'une bibliothèque côté client, un intercepteur peut être implémenté pour supprimer le tableau externe avant de le renvoyer à l'application.
la source
Pour Magento 2.3.1, si vous devez contourner la sérialisation de la baie, vous pouvez vérifier ce fichier pour mettre à jour la logique principale. Je pense que c'est un bon point d'entrée. Mais en faisant cela, vous casserez la compatibilité Soap à coup sûr.
De plus sur Magento 2.1.X, vous n'avez pas ce problème si vous mettez anyType comme type de retour.
Référence Github: https://github.com/magento/magento2/blob/2.3-develop/lib/internal/Magento/Framework/Reflection/TypeCaster.php
Validation de la référence de changement: https://github.com/magento/magento2/commit/6ba399cdaea5babb373a35e88131a8cbd041b0de#diff-53855cf24455a74e11a998ac1a871bb8
vendeur / magento / framework / Reflection / TypeCaster.php: 42
Et remplacez par:
la source
Je sais que cette question est assez ancienne, mais il existe une solution assez simple à cela:
Vous devez soit remplacer Json-Renderer,
Magento\Framework\Webapi\Rest\Response\Renderer\Json
soit écrire un plugin pour celui-ci.Voici un petit exemple de plugin:
Dans ton
di.xml
Dans votre nouvelle classe de plugins
Namespace\Module\Plugin\Webapi\RestResponse\JsonPlugin
Que se passe t-il ici:
Bien sûr, vous pouvez également écrire votre propre moteur de rendu, qui traite un tableau par exemple.
la source
J'ai fait face au même problème et il m'a fallu un certain temps pour comprendre le problème.
Magento fait quelque chose de bizarre dans le processeur de sortie du service API Web qui se trouve sous Magento \ Framework \ Webapi \ ServiceOutputProcessor. Dans cette classe, il existe une méthode nommée convertValue (); ce qui est la raison des accolades [].
La meilleure solution pour moi de résoudre le problème était de créer un plugin around pour surmonter cette condition if dans convertValue (); méthode où ils vérifient si $ data est un tableau et font ce truc bizarre avec.
Voici mon exemple de code du plugin: je pense que tout le monde sait comment créer un module de base Magento 2, donc je ne poste que le code du plugin lui-même ici.
Créer un dossier de plugin
Créez une classe Vendor \ ModuleName \ Plugin \ ServiceOutputProcessorPlugin.php
Cela devrait résoudre le problème de sortie du tableau json dans l'API Web
J'espère que cela t'aides
la source