Skip to content

feat: add enhanced middleware support #1479

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

Merged
merged 35 commits into from
Jul 30, 2022
Merged

Conversation

ascorbic
Copy link
Contributor

@ascorbic ascorbic commented Jul 22, 2022

Summary

This demo shows a way of adding some of the powers of Netlify Edge Functions to Next.js Middleware. Normal Next.js middleware doesn't provide actual access to the Response but rather allows the user to return a NextResponse object which is just used by the handler to set headers etc on the real response when it is returned. Calling NextResponse.next() doesn't actually send a request to the origin, but is just a placeholder for setting response headers which are applied later. It also does not allow changes to be made to the Request, but instead allows a rewrite() to be returned, which the wrapper uses to change the request. This library gives proper access to Request and Response in much the same way that Netlify Edge Functions do, but with some additional Next-specific helpers.

Full details here: https://github.com/netlify/pod-ecosystem-frameworks/issues/183

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for next-hp-edge-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/next-hp-edge-demo/deploys/62e448161b8e0300083bce9f
😎 Deploy Preview https://deploy-preview-1479--next-hp-edge-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for netlify-plugin-nextjs-nx-monorepo-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-nx-monorepo-demo/deploys/62e44815a7f0fb00080aa6a2
😎 Deploy Preview https://deploy-preview-1479--netlify-plugin-nextjs-nx-monorepo-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for netlify-plugin-nextjs-export-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-export-demo/deploys/62e448167692b90009fdee48
😎 Deploy Preview https://deploy-preview-1479--netlify-plugin-nextjs-export-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for netlify-plugin-nextjs-static-root-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-static-root-demo/deploys/62e44815059a0b00084da79a
😎 Deploy Preview https://deploy-preview-1479--netlify-plugin-nextjs-static-root-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@github-actions github-actions bot added the type: feature code contributing to the implementation of a feature and/or user facing functionality label Jul 22, 2022
@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for netlify-plugin-nextjs-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-demo/deploys/62e44815faea960009e8fe25
😎 Deploy Preview https://deploy-preview-1479--netlify-plugin-nextjs-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for next-plugin-edge-middleware ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-edge-middleware/deploys/62e44816fb87370009896153
😎 Deploy Preview https://deploy-preview-1479--next-plugin-edge-middleware.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for next-plugin-rsc-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-rsc-demo/deploys/62e44816d323e50008b8f082
😎 Deploy Preview https://deploy-preview-1479--next-plugin-rsc-demo.netlify.app/
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for next-i18next-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/next-i18next-demo/deploys/62e44816aea9da00084370f7
😎 Deploy Preview https://deploy-preview-1479--next-i18next-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for netlify-plugin-nextjs-next-auth-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-next-auth-demo/deploys/62e448161696390009c55315
😎 Deploy Preview https://deploy-preview-1479--netlify-plugin-nextjs-next-auth-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for next-plugin-canary ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-canary/deploys/62e448169c8ac10008c0af03
😎 Deploy Preview https://deploy-preview-1479--next-plugin-canary.netlify.app/
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@netlify
Copy link

netlify bot commented Jul 22, 2022

Deploy Preview for nextjs-plugin-custom-routes-demo ready!

Name Link
🔨 Latest commit 6c5664e
🔍 Latest deploy log https://app.netlify.com/sites/nextjs-plugin-custom-routes-demo/deploys/62e44816cb7f5f0008521f6f
😎 Deploy Preview https://deploy-preview-1479--nextjs-plugin-custom-routes-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@cypress
Copy link

cypress bot commented Jul 22, 2022



Test summary

7 0 0 0


Run details

Project netlify-plugin-nextjs-static-demo
Status Passed
Commit 6c99c10 ℹ️
Started Jul 29, 2022 8:53 PM
Ended Jul 29, 2022 8:54 PM
Duration 01:13 💡
OS Linux Ubuntu - 20.04
Browser Chrome 103

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@cypress
Copy link

cypress bot commented Jul 22, 2022



Test summary

2 0 0 0


Run details

Project netlify-plugin-nextjs-nx-monorepo-demo
Status Passed
Commit 6c99c10 ℹ️
Started Jul 29, 2022 8:53 PM
Ended Jul 29, 2022 8:54 PM
Duration 01:09 💡
OS Linux Ubuntu - 20.04
Browser Chrome 103

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@cypress
Copy link

cypress bot commented Jul 22, 2022



Test summary

22 0 0 0


Run details

Project netlify-plugin-nextjs-default-demo
Status Passed
Commit 6c99c10 ℹ️
Started Jul 29, 2022 8:53 PM
Ended Jul 29, 2022 8:55 PM
Duration 01:23 💡
OS Linux Ubuntu - 20.04
Browser Chrome 103

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@ascorbic ascorbic force-pushed the mk/rewrite-props-middleware branch from 2f92ed1 to b0d9952 Compare July 23, 2022 06:31
@ascorbic ascorbic force-pushed the mk/rewrite-props-middleware branch from b0d9952 to a2c88b7 Compare July 23, 2022 06:40
@ascorbic ascorbic force-pushed the mk/rewrite-props-middleware branch from fbb2223 to ba284d9 Compare July 23, 2022 12:55
@ascorbic
Copy link
Contributor Author

OK, I've had a rethink about naming and changed it to MiddlewareRequest and MiddlewareResponse, which is generic and easier to understand. I think that middlewareRequest.rewrite() (or redirect() or next()) returning a MiddlewareResponse seems more intuitive.

@ascorbic ascorbic force-pushed the mk/rewrite-props-middleware branch from b82d367 to d4c0dc0 Compare July 27, 2022 09:20
@ascorbic
Copy link
Contributor Author

OK, I'm marking this ready for review. I suggest we put this out so people can try it. It's opt-in, so shouldn't affect anything. We may decide to publish it in a separate package, but right now it can be imported from here.

@ascorbic ascorbic marked this pull request as ready for review July 28, 2022 14:46
@ascorbic ascorbic requested a review from a team July 28, 2022 14:46
Copy link

@ericapisani ericapisani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small things within the code itself, but I'm noticing there's no automated test coverage for the new functionality.

Is the plan to add some tests in a follow up?


import { MiddlewareResponse } from './response'

// TODO: add Context type

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this comment can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I mean the real context type, if it gets published at some point

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type NextDataTransform = <T extends Record<string, any>>(props: T) => T

// A NextReponse that wraps the Netlify origin response

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[dust] small typo

Suggested change
// A NextReponse that wraps the Netlify origin response
// A NextResponse that wraps the Netlify origin response

@ascorbic
Copy link
Contributor Author

So it turns out we don't have middleware e2e tests at all, so I've added some, including tests for the new stuff.

let response
const {
nextUrl: { pathname },
} = request
} = req

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[dust] Use the full name request and response for variable names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request and response are already used for the MiddlewareRequest and MiddlewareResponse. I considered changing them to nextRequest and nextResponse but thought it made the code examples a bit verbose. Hard to say which is better tbh

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realise I've mixed the different styles, so yeah this should be tidied up in a follow-up.

import type { ElementHandlers } from './html-rewriter'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type NextDataTransform = <T extends { pageProps?: Record<string, any> }>(props: T) => T

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[dust] Prefer unknown

Suggested change
export type NextDataTransform = <T extends { pageProps?: Record<string, any> }>(props: T) => T
export type NextDataTransform = <T extends { pageProps?: Record<string, unknown> }>(props: T) => T

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I didn't do this is because it would mean that users would need to create a type and explicitly cast the props value whenever they used transformData, which could be quite cumbersome. I'll add a comment.


get headers(): Headers {
// If we have the origin response, we should use its headers
return this.originResponse?.headers || super.headers

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[dust] Prefer nullish coalescing.

Suggested change
return this.originResponse?.headers || super.headers
return this.originResponse?.headers ?? super.headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love nullish coalescing, but IMO it's only worth using if there's a legitimate reason for the value to be falsy. Otherwise it just introduces a (tiny) bit of extra transpiled code and execution time for no reason. This will either be a Headers object or undefined, so a simple || does the job.

Copy link

@nickytonline nickytonline left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @ascorbic! This is definitely in a great place where folks can start playing with this. 🚀

@kodiakhq kodiakhq bot merged commit 689b2ac into main Jul 30, 2022
@kodiakhq kodiakhq bot deleted the mk/rewrite-props-middleware branch July 30, 2022 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge type: feature code contributing to the implementation of a feature and/or user facing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants