2017-07-07 2 views
1

Une API J'écris accepte deux arguments via l'URL - par exemple/api/cibles/toto/titiComment transmettre des paramètres supplémentaires à dispatch()?

app = webapp2.WSGIApplication([ 
    ('/api/targets/(\w*?)/(\w*?)$', MainPage), 
], debug=True) 

Ce Déclenché un gestionnaire GET:

def get(self, url_1, url_2): 
    #do some stuff 

La chose cool ici est que Je peux référencer url_1 (truc) et url_2 (barre) dans mon gestionnaire GET et ils sont définis pour moi.

J'ai une autre page qui accepte les requêtes GET et POST. Environ 90% de ce qui se passe est le même dans les deux cas, j'ai donc choisi d'utiliser def dispatch() au lieu d'avoir deux gestionnaires distincts.

Le problème ici est que (même si j'ai encore les blocs regex enfermés dans mon Initialisation webapp2.WSGIApplication), ils ne sont plus transmis au gestionnaire de requêtes, donc je dois les définir comme ceci:

url_1= self.request.url.split("/")[3] 
    url_2= self.request.url.split("/")[4] 

Ce qui me fait sentir comme un péon. Si je dis à dispatch() d'attendre ces deux paramètres, ils n'arrivent jamais. Que dois-je faire pour imiter le comportement de get dans dispatch?

Répondre

1

Il serait plus court à utiliser:

arg_one = self.request.route_args[0] 
arg_two = self.request.route_args[1] 

Jetez un oeil à la webapp2 docs pour l'objet de demande, en particulier la route_args et route_kwargs vers le bas de la section de demande.

Ceci est un cas d'utilisation intéressant. Si j'étais vous, je garderais get() et post() séparé. Si get() et post() partagent le code, alors je déplacerais ce code vers une méthode de RequestHandler qui peut être appelée depuis get() et post(), ou déplacer le code partagé dans une autre classe (je trouve beaucoup de mes RequestHandlers appellent simplement des méthodes sur mes classes de modèles).

Si vous souhaitez toujours remplacer une méthode par get() et post(), au lieu d'utiliser dispatch(), je vous recommande de définir handler_method pour l'itinéraire (voir here in the docs). Je déconseille de gérer ces requêtes entièrement dans la méthode dispatch(), car cela est supposé, à un moment donné, appeler la méthode "handler", qui est par défaut GET/POST/etc. basé sur la méthode HTTP, mais vous pouvez définir votre propre méthode de gestionnaire pour gérer GET et POST et tout le reste.

Si vous définissez le handler_method, il ressemblerait à ceci:

# note that handler_method is the method name as a string 
app = webapp2.WSGIApplication([ 
    ('/api/targets/(\w*?)/(\w*?)$', MainPage, handler_method='handle_request'), 
], debug=True) 

Dans votre gestionnaire:

class MainPage(webapp2.RequestHandler): 
    # note that your method signature MUST have args for the route args, 
    # or else an exception will occur 
    def handle_request(self, arg_one, arg_two): 
     # your code here 
     if self.request.method == 'GET': 
      # do GET stuff 
     elif self.request.method == 'POST': 
      # do POST stuff 

C'est agréable car elle laisse dispatch() inchangé. J'aime penser à dispatch() avant et après le traitement avant/après l'appel de get()/post()/quelle que soit la méthode de gestion que vous spécifiez.

+1

Je ne sais pas pourquoi cela m'a pris un mois à remarquer, mais une réponse parfaite. Bien expliqué, patient et constructif. Merci beaucoup :) –