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

feat: Upgrade to express 5.0.1 #9530

Open
wants to merge 15 commits into
base: alpha
Choose a base branch
from

Conversation

pocketcolin
Copy link

@pocketcolin pocketcolin commented Jan 10, 2025

Pull Request

Issue

Closes: #9353

Approach

Express 5 is not a huge change from 4, but it does introduce some breaking changes and deprecates body-parser (well technically that was replaced in a later version of 4, but I decided to clean it up in this PR anyway). Here are the main changes that impacted Parse Server in this upgrade and how I addressed them:

  1. Express moved route validation to a separate package called router. In Parse, path parameter validation is done using an Express class called Layer which is now in that router package so I added the new package and updated the import.
  2. req.body is now undefined if the body has not been parsed OR if there is no body. Previously, it returned an empty object. Because Parse attempts to access keys on body without verifying that it exists, I had to go through and update all unsafe reference attempts or places where body was passed to a function.
  3. body-parser has been replaced with native express functions. Updating this just meant swapping bodyParser with express and removing the package.
  4. urlencoded now defaults to false. I decided against removing the explicit setting of that property in ParseServer.js as a personal preference for more explicit declarations. It is no longer technically necessary though.
  5. Express 4 had a routing oddity that made double forward slashes between the router and route legal (discussed here: Double slash before Router (router//route) expressjs/express#4427). Definitely an anti-pattern, but unfortunately the Parse JS SDK actually uses it in the Hooks router. For the sake of backwards compatibility, I added a middleware that strips out the extra slash.
  6. In Express 4, extended query params were parsed automatically, but in Express 5 you have to explicitly tell it to do that by setting query parser to extended (setting defined here: https://expressjs.com/en/5x/api.html#app.set).
  7. Express 5 does not allow unnamed wildcard parameters. The only place Parse is using those is for custom static routes so I updated that and gave it a name. (https://expressjs.com/en/guide/migrating-5.html#path-syntax)

I also updated the package.json test scripts to use MongoDB 6.0.2 because 5.3.2 doesn't exist and you'll get an error if you try to run a test locally with that version.

Testing

The Express migration guide and release announcement was used to validate breaking changes:

Copy link

Thanks for opening this pull request!

@pocketcolin pocketcolin changed the title upgraded to express 5 with tests passing feat: upgraded to express 5 from 4 Jan 10, 2025
Copy link

I will reformat the title to use the proper commit message syntax.

@parse-github-assistant parse-github-assistant bot changed the title feat: upgraded to express 5 from 4 feat: Upgraded to express 5 from 4 Jan 10, 2025
@mtrezza
Copy link
Member

mtrezza commented Jan 10, 2025

Nice! It seems there are no breaking changes for developers in this PR, correct? I've started the CI.

package.json Outdated Show resolved Hide resolved
@pocketcolin
Copy link
Author

@mtrezza I don't believe there are any! I also ran my app server's integration tests against the new build and they all passed.

@mtrezza mtrezza changed the title feat: Upgraded to express 5 from 4 feat: Upgrade to express 5.0.1 Jan 10, 2025
@mtrezza
Copy link
Member

mtrezza commented Jan 10, 2025

Do you know whether there are any effects on Parse Server that come with the upgrade? If there are no known effects, then we could merge this as a refactor (just like we do with any other dependency upgrade), which would not trigger a release.

@pocketcolin
Copy link
Author

That kinda depends on what you mean by effects. I haven't nailed down exactly why, but I haven't been able to update my app's version of Express to 5 without Parse crashing (stream is not readable) so this PR will allow users to upgrade to Express 5 in their apps and take advantage of all it has to offer. I'd suggest that because Express is such a core part of Parse and Express's upgrade from 4 to 5 was not a refactor, that upgrading Parse to use 5 is also not a refactor. That said, this change doesn't require anyone to make any updates so I could see going either way.

I'm seeing some errors in the tests that I was't seeing before so once those are fixed it I might find some more effects that would make the decision easier.

@mtrezza mtrezza added the state:breaking Breaking change requires major version increment and `BREAKING CHANGE` commit message label Jan 12, 2025
@mtrezza
Copy link
Member

mtrezza commented Jan 12, 2025

I've marked this as a breaking change as a precaution; more analysis is needed before we can merge this and know whether it actually is a breaking change, or what its effects are.

  • Does it require that express 5.x is used to run Parse Server, like in the parse-server-example repo where express is used to mount Parse Server, or will it stay compatible with express 4.x?

@pocketcolin
Copy link
Author

That's fair, @mtrezza . To answer your one question though, I have tested this against a implementation running Express 4 without any issues so I believe this change will stay compatible with 4.x.

@pocketcolin
Copy link
Author

@mtrezza ok I've made a number of changes to get all of the tests passing and will update the PR description to reflect this. I still have not found anything that I would consider a breaking change, but these are the remaining things I found:

  • Express 4 had a routing oddity that made double forward slashes between the router and route legal. Definitely an anti-pattern, but unfortunately the Parse JS SDK actually uses it in the Hooks router. It would probably be a good idea to fix the Parse JS SDK so it didn't add a double slash, but for the sake of backwards compatibility, I added a middleware that strips out the extra slash. I'll also create a ticket in the JS SDK to clean this up.
  • In Express 4, extended query params were parsed automatically, but in Express 5 you have to explicitly tell it to do that by setting query parser to extended.
  • Express 5 does not allow unnamed wildcard parameters. The only place Parse is using those is for custom static routes so I updated that and gave it a name.

@pocketcolin pocketcolin requested a review from mtrezza January 13, 2025 21:15
@mtrezza
Copy link
Member

mtrezza commented Jan 13, 2025

Good investigation, I've started the CI.

Copy link

codecov bot commented Jan 13, 2025

Codecov Report

Attention: Patch coverage is 97.87234% with 1 line in your changes missing coverage. Please review.

Project coverage is 93.51%. Comparing base (28b3ede) to head (6b7b76e).

Files with missing lines Patch % Lines
src/Routers/GraphQLRouter.js 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##            alpha    #9530   +/-   ##
=======================================
  Coverage   93.50%   93.51%           
=======================================
  Files         186      186           
  Lines       14807    14809    +2     
=======================================
+ Hits        13845    13848    +3     
+ Misses        962      961    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@pocketcolin
Copy link
Author

@mtrezza all of the tests passed except for a series of 8 that failed for issues related to a bad cert.

  - Error: Hostname/IP does not match certificate's altnames: Host: cacerts.digicert.com. is not in the cert's altnames: DNS:ocsp.digicert.com

Any idea what that's about?

The code coverage in that report also seems fine to me but let me know what you think. I don't really think we need a test to cover that tiny conditional, but let me know if you feel differently!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state:breaking Breaking change requires major version increment and `BREAKING CHANGE` commit message
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Upgrade express from 4 to 5
3 participants