J'ai une route générique comme ci-dessous - et j'ai une version v2 de la même manière ci-dessous - p> i avoir un problème à résoudre - p> le frontend frappe toujours le V1 de l'API (la route générique). J'ai besoin de rediriger interne à V2, en fonction du paramètre Comment puis-je faire cela dans un acheminement de framework slim sans émettre des en-têtes de redirection 302 au client? Fondamentalement, j'ai besoin de rediriger à l'intérieur du serveur lui-même. P> NOTE: STROND> Je suis au courant des réécrites NGinx et Apache. Laissez-nous les garder de côté et limiter la portée à l'axe-cadre mince seul. P> P> de la valeur code> de la valeur code>. Em> p>
3 Réponses :
Vous devez abstrumer vos invocations et créer des contrôleurs (c'est-à-dire que votre code ne sera pas aussi mince).
Exemple: P>
function doV2() { // ... do V2 things } function doV1() { // ... do V1 things } $app->map(['GET', 'POST'], "/", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) { if($app->request()->params('appversion') === 'v2') return doV2(); doV1(); } $app->map(['GET', 'POST'], "/api/v2", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) { doV2(); }
Merci pour cette approche. Certainement celui qui fonctionne. Marquera ceci comme réponse acceptée si je ne pouvais pas trouver une meilleure façon, dans les prochaines 24 heures.
Je le ferais en utilisant Segments facultatifs Dans une définition unique de route.
use Psr\Http\Message\{ ServerRequestInterface as Request, ResponseInterface as Response }; $app->map(['GET', 'POST'], '/[{v2:api/v2}]', function (Request $request, Response $response, array $args) { if (isset($args['v2'])) { // You may also check $request->getAttribute('appversion') // Version 2 processing here... // return $response; } // Version 1 processing here... // return $response; });
Mais je dois décider en fonction d'une question de requête plutôt que d'une phrase URI.
Si vous souhaitez décider basé sur la requête Param, vous pouvez obtenir la valeur de param param à l'aide de $ Demande-> getparam ("apparversion ') code> ou si vous envisagez d'injecter des valeurs dans l'objet de la demande, vous pouvez vérifier
$ Demande-> getattribute ("apparversion") code>.
Ce que vous voulez réaliser est techniquement possible, mais pour moi, il semble que la raison de votre question soit que vous souhaitez introduire une nouvelle version de votre API, mais vous ne voulez pas (ou vous ne pouvez pas) mettre à jour le devant Fin pour appeler la nouvelle version et, à la place, vous souhaitez gérer cela dans l'arrière-plan.
Si vous allez décider quelle version de votre API doit être appelée sur la base de Si une personne appelle votre Appversion code> mais pas Le noeud final qui a été touché, alors quel est l'avantage de la définition de
V1 code> et
v2 code> des points d'extrémité? p>
v1 code > Endpoint, ils veulent que votre réponse
v1 code> et si une personne a besoin de votre réponse
v2 code>, ils doivent appeler votre point de terminaison
v2 code>. Si vous renvoyez la même réponse pour les deux
V1 code> et
v2 code>, vous mettez en phase de mise à jour de votre
V1 code> Comportement de terminaison. P> Quoi qu'il en soit, vous souhaitez envoyer un autre itinéraire dans un autre itinéraire rappel, et voici un exemple de travail complet montrant comment cela se fait à l'aide d'un
Sous-lieu code>: p>
<?php
require 'vendor/autoload.php';
$app = new \Slim\App;
$app->map(['GET', 'POST'], '/v1', function($request, $response) use ($app) {
// Get the appversion query parameter and make the decision based on its value
$appVersion = $request->getParam('appversion');
if($appVersion == '1.0') {
return $app->subRequest($request->getMethod(), '/v2',
http_build_query($request->getQueryParams()),
$request->getHeaders(),
$request->getCookieParams(),
$request->getBody()->getContents()
);
}
return 'API version: v1, appversion: ' . $appVersion;
});
$app->map(['GET', 'POST'], '/v2', function($request, $response) {
return 'API version: v2, request method: ' . $request->getMethod() .', appversion: '. $request->getParam('appversion') . ', body: <pre>' . print_r($request->getParsedBody(), 1);
});
$app->get('/form', function() {
return <<<form
<form method="POST" action="/v1?appversion=1.0">
<input type="text" name="foo" value="bar">
<button type="submit" value="submit">Submit</button>
</form>
form;
});
$app->run();
À notre malheureux chance, le frontend est une application Android qui a été publiée à PlayStore avec un point d'extrémité codé du V1, alors qu'il s'attend à ce que certains paramètres supplémentaires (que V2 fournit) pour permettre quelques nouvelles fonctionnalités. Quoi qu'il en soit, merci pour la réponse. J'ai essayé de faire des travaux de contournement similaires, mais j'ai échoué à transmettre le corps de poste dans l'appel subrequest (). Y-a-t-il un moyen de faire ça? Le corps de poste sera juste une chaîne de JSON codée.
C'est possible. Veuillez lire Documentation de la méthode de la sous-préquête () A > et regardez l'exemple mis à jour dans ma réponse. J'ai ajouté un formulaire pour tester la requête code> Post Code>.
Merci beaucoup. C'est exactement ce dont j'avais besoin. Vous vous demandez comment j'ai manqué Documentation pour la méthode subrequest () I>.
Qu'en est-il de
$ app-> rediriger ('/ books', '/ bibliothèque'); code>?
Cela émet une redirection de 302 au client. Je veux éviter cela pour sauver l'heure de retour de retour indésirable.
Désolé, ce serait
$ app-> rediriger ('/ livres', '/ bibliothèque', 301); code>.
$ App-> Redirection () Code> Répondre au client avec un en-tête de redirection, 301 ou 302 ou des autres. Si vous pensez à ce qui se passe ensuite, le serveur Web répond avec le statut 301/302 avec
emplacement code> en-tête, au client. Le navigateur client interprète ensuite ces informations d'en-tête et initie une nouvelle requête HTTP avec la valeur de l'emplacement code> code> de l'en-tête. J'essaie d'éviter de retourner au client avec un en-tête de redirection, tout à fait b>.