CodeGenieApp / CodeGenieApp/serverless-express

Routing to root path does not work correctly when using nested API resources

Ouverte
#377 0 commentaires 6 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
JavaScript
Étoiles
5.3k
Forks
674
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

First off, thanks for this great project!

I'm reporting an issue here I ran into when using API Gateway v1 with a proxy resource.

Repro

I have defined a RestAPI resource triggered on a nested root path and subpaths under a /v1/ path namespace. The SAM template looks like this:

      Events:
        ProxyApiRoot:
          Type: Api
          Properties:
            RestApiId: !Ref ExpressApi
            Path: /v1/
            Method: ANY
        ProxyApiGreedy:
          Type: Api
          Properties:
            RestApiId: !Ref ExpressApi
            Path: /v1/{proxy+}
            Method: ANY

I also have a BasePathMapping defined nesting one level deeper, so the final root path for my app is /routes/v1/.

My express app has a handler defined for the root path:

router.get('/', (req, res) => { ... }

However a request to <host>/routes/v1/ returns a generic 404 from express. The request is routing correctly through API Gateway to my app, but once it gets to express it can't find a matching handler for the / path.

Debugging

I added a handler for the catch-all route * and printed out the currentInvoke to try to track down the problem. I think I narrowed it down to this line:

https://github.com/vendia/serverless-express/blob/4ba9799a6573ea4227939001c3e49e07b75a35ea/src/event-sources/utils.js#L6-L7

The issue is that my request to /routes/v1/ is being handled by ProxyApiRoot, not ProxyApiGreedy. Since ProxyApiRoot doesn't populate a value for event.pathParameters.proxy, the fallback event.path is used. But unlike pathParameters.proxy, event.path includes the full path including the namespaces. So for a request to the root of my app, serverless-express is interpreting the path as event.path == '/routes/v1', not event.path == '/'.

Solution?

There may need to be more smarts added to getPathWithQueryStringParams for stripping out prefixes from the root path.

For example from printing out the currentInvoke I found:

  • The base path part is available at event.requestContext.customDomain.basePathMatched == 'routes'
  • The v1 part is available at event.resource = '/v1'.

Perhaps these can be used to remove /routes/v1 from the root path when event.pathParameters.proxy is not populated.

Workaround

In the short term I found a workaround by avoiding root paths altogether. My SAM template now looks like:

        ProxyApiGreedy:
          Type: Api
          Properties:
            RestApiId: !Ref ExpressApi
            Path: /{proxy+}
            Method: ANY

and I mount all my express routes at v1 explicitly using app.use('/v1', router).

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans src/event-sources/utils.js, au niveau de getPathWithQueryStringParams, puis reproduisez les routes imbriquées /v1/ et /v1/{proxy+} de SAM API Gateway avec le mapping de chemin de base /routes/v1/. Suivez les champs de l’événement utilisés pour la requête racine, en particulier event.path, event.resource, event.requestContext.customDomain.basePathMatched et event.pathParameters.proxy. C’est terminé lorsque le gestionnaire racine Express reçoit / au lieu du chemin avec espace de noms.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
aws, express, javascript, node.js
Domaine
api, backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.