nestjs / serve-static

Serve static websites (SPA's) using Nest framework (node.js) 🥦

Home Page:https://nestjs.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ignore routes for serve-static on api endpoints

darrenjennings opened this issue · comments

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Currently if you serveStatic alongside api routes, it would be nice if you could tell serve-static to ignore paths beginning with /api via some options. This would allow /api/not-found to return 404 from API, and not try and serve an index.html file. If there is some current way to do it, I'm also curious how I might get around this with middleware if necessary.

Expected behavior

The /api routes do not serve static on 404s.

Minimal reproduction of the problem with instructions

Run a boilerplate nestjs app with serveStatic. add app.setGlobalPrefix('api') and then try and hit /api/not-found-route-goes-here and it will serve the index.html.

What is the motivation / use case for changing the behavior?

monorepo api + webapp

Environment


Nest version: 6.12.9

 
For Tooling issues:
- Node version: v12.13.0  
- Platform: Mac  

Others:
N/A

I think renderPath of ServeStaticModuleOptions can do this.

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
      renderPath: '/',
    }),
  ],
})
export class ApplicationModule {}

If you set path for index.html to renderPath, index.html is only served when accessing your setting path.

In the above code,
localhost:3000 can only render index.html, and the others will return 404, for example localhost:3000/api.

@mishio-n this does not solve the problem. It just shifts the problem to another case.

From my point of view the behavior can be described as follows:

Endpoints Expected Behavior Current Behavior @mishio-n Behavior
/ serves index.html serves index.html serves index.html
/api/not-found-route-goes-here JSON 404 Response serves index.html JSON 404 Response
/not-found-route-goes-here serves index.html serves index.html JSON 404 Response

The goal should be to return a 404 status code on not existing api endpoints. This would indicate possible problems like misspelling of the endpoint to the developers.

On the other hand the response of non api endpoints should always be the index.html so the SPA can decide how the 404 page should look like.

The exclude option has been added in 2.0.0. See example here https://github.com/nestjs/nest/tree/master/sample/24-serve-static

@kamilmysliwiec I just upgraded to 2.0.0, added the exclude but still seeing static files served:

ServeStaticModule.forRoot({
  rootPath: join(__dirname, '..', '..', 'client/public'),
  exclude: ['/api*'],

Expected:

▶ http :3000/api/this-should-404
HTTP/1.1 404 NOT FOUND

Acual:

▶ http :3000/api/this-should-404
GET /api/this-should-404 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
...
HTTP/1.1 200 OK
...
<!DOCTYPE html>
#<HTML OF STATIC INDEX.HTML HERE>

@darrenjennings are you using express or fastify?

Express

@kamilmysliwiec I was able to get it to work with:

exclude: ['/api/(.*)'],

I looked at the regex returned from the path-to-regexp in the isRouteExcluded util. The latest version of the library (https://forbeslindesay.github.io/express-route-tester/) returns this regexp:

// '/api*'
^\/api\/(.*)\/?(?=\/|$)

but the code in my node_modules is returning which seems to disregard that a wildcard needs to be transformed:

// '/api*'
^\/api\/\*(?:\/(?=$))?$

So it could be some dependency version resolving to an older version as it seems my lockfile has many versions of path-to-regexp. Looks my local is resolving to 0.2.5.