Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to disable API warning #11380

Merged
merged 2 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/api-routes/api-middlewares.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ export const config = {
}
```

`externalResolver` is an explicit flag that tells the server that this route is being handled by an external resolver like _express_ or _connect_. Enabling this option disables warnings for unresolved requests.

```js
export const config = {
api: {
externalResolver: true,
},
}
```

## Connect/Express middleware support

You can also use [Connect](https://github.com/senchalabs/connect) compatible middleware.
Expand Down
8 changes: 7 additions & 1 deletion packages/next/next-server/server/api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export async function apiResolver(
}
const config: PageConfig = resolverModule.config || {}
const bodyParser = config.api?.bodyParser !== false
const externalResolver = config.api?.externalResolver || false

// Parsing of cookies
setLazyProp({ req: apiReq }, 'cookies', getCookieParser(req))
Expand Down Expand Up @@ -70,7 +71,12 @@ export async function apiResolver(
// Call API route method
await resolver(req, res)

if (process.env.NODE_ENV !== 'production' && !isResSent(res) && !wasPiped) {
if (
process.env.NODE_ENV !== 'production' &&
!externalResolver &&
!isResSent(res) &&
!wasPiped
) {
console.warn(
`API resolved without sending a response for ${req.url}, this may result in stalled requests.`
)
Expand Down
6 changes: 6 additions & 0 deletions packages/next/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export type PageConfig = {
* format supported by `bytes`, for example `1000`, `'500kb'` or `'3mb'`.
*/
bodyParser?: { sizeLimit?: number | string } | false
/**
* Flag to disable warning "API page resolved
* without sending a response", due to explicitly
* using an external API resolver, like express
*/
externalResolver?: true
}
env?: Array<string>
unstable_runtimeJS?: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default (_req, res) => {
setTimeout(() => {
res.send('hello world')
}, 0)
}
11 changes: 11 additions & 0 deletions test/integration/api-support/pages/api/external-resolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default (_req, res) => {
setTimeout(() => {
res.send('hello world')
}, 0)
}

export const config = {
api: {
externalResolver: true,
},
}
19 changes: 19 additions & 0 deletions test/integration/api-support/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,25 @@ function runTests(dev = false) {
`API resolved without sending a response for /api/test-res-pipe`
)
})

it('should show false positive warning if not using externalResolver flag', async () => {
const apiURL = '/api/external-resolver-false-positive'
const req = await fetchViaHTTP(appPort, apiURL)
expect(stderr).toContain(
`API resolved without sending a response for ${apiURL}, this may result in stalled requests.`
)
expect(await req.text()).toBe('hello world')
})

it('should not show warning if using externalResolver flag', async () => {
const startIdx = stderr.length > 0 ? stderr.length - 1 : stderr.length
const apiURL = '/api/external-resolver'
const req = await fetchViaHTTP(appPort, apiURL)
expect(stderr.substr(startIdx)).not.toContain(
`API resolved without sending a response for ${apiURL}`
)
expect(await req.text()).toBe('hello world')
})
} else {
it('should show warning with next export', async () => {
const { stdout } = await nextExport(
Expand Down