Skip to content

feat: nextrouter pkg to handle nextjs routing rules #167

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 43 commits into from
Feb 9, 2022

Conversation

bryphe-coder
Copy link
Contributor

@bryphe-coder bryphe-coder commented Feb 5, 2022

An issue came up last week... our embed.go strategy doesn't handle dynamic NextJS-style routes! This is a blocker, because I'm aiming to set up CD on Monday, and the v2 UI makes heavy use of dynamic routing.

As a potential solution, this implements a go pkg nextrouter that serves html files, but respecting the dynamic routing behavior of NextJS:

  • Files that have square brackets - ie [providers] provide a single-level dynamic route
  • Files that have [[... prefix - ie [[...any]] - are catch-all routes.
  • Files should be preferred over folders (ie, providers.html is preferred over /providers)
  • Fixes the trailing-slash bug we hit in the previous embed strategy

This also integrates with slog.Logger for tracing, and handles injecting template parameters - a feature we need in v1 and v2 to be able to inject stuff like CSRF tokens.

This implements testing by using an in-memory file-system, so that we can exercise all of these cases.

In addition, this adjust V2's embed.go strategy to use nextrouter, which simplifies that file considerably. I'm tempted to factor out the secureheaders logic into a separate package, too.

If this works OK, it could be used for V1 too (although that scenario is more complex due to our hybrid-routing strategy). Based on our FE variety meeting, there's always a chance we could move away from NextJS in v1 - if that's the case, this router will still work and be more tested than our previous strategy (it just won't make use of dynamic routing). So I figured this was worth doing to make sure we can make forward progress in V2.

@bryphe-coder bryphe-coder self-assigned this Feb 5, 2022
@codecov
Copy link

codecov bot commented Feb 5, 2022

Codecov Report

Merging #167 (e4d031f) into main (61b3909) will increase coverage by 3.37%.
The diff coverage is 74.35%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #167      +/-   ##
==========================================
+ Coverage   64.66%   68.03%   +3.37%     
==========================================
  Files          58      111      +53     
  Lines         648     6004    +5356     
  Branches       68       68              
==========================================
+ Hits          419     4085    +3666     
- Misses        217     1526    +1309     
- Partials       12      393     +381     
Flag Coverage Δ
unittest-go-macos-latest 65.87% <74.35%> (?)
unittest-go-ubuntu-latest 67.49% <74.35%> (?)
unittest-go-windows-latest 65.82% <74.35%> (?)
unittest-js 64.66% <ø> (ø)
Impacted Files Coverage Δ
site/embed.go 83.14% <31.25%> (ø)
site/nextrouter/nextrouter.go 79.13% <79.13%> (ø)
coderd/coderd.go 94.50% <100.00%> (ø)
codersdk/workspaces.go 73.73% <0.00%> (ø)
httpmw/userparam.go 76.66% <0.00%> (ø)
database/migrate.go 52.38% <0.00%> (ø)
provisionerd/provisionerd.go 68.29% <0.00%> (ø)
database/pubsub_memory.go 87.17% <0.00%> (ø)
httpmw/provisionerjobparam.go 78.37% <0.00%> (ø)
peer/netconn.go 30.00% <0.00%> (ø)
... and 45 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 61b3909...e4d031f. Read the comment docs.

Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

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

This is unfortunate but seems necessary.

Instead of this, could we do the following:

  1. Enable trailingSlash in next.config.js so all files are named index.html.
  2. Manually specify parameterized routes. This sucks, but I'm nervous to add a few hundred lines of routing code (albeit tested) when we could add like: router.Match("/projects/{organization}/{project}", serveStaticHandler)

Thoughts?

@bryphe-coder
Copy link
Contributor Author

bryphe-coder commented Feb 5, 2022

Manually specify parameterized routes. This sucks, but I'm nervous to add a few hundred lines of routing code (albeit tested) when we could add like: router.Match("/projects/{organization}/{project}", serveStaticHandler)

I thought about this after our discussion and FE variety yesterday - but I'm not a fan, because it seems too hard to maintain. The problem is our development environment with ./develop works w/o having to specify paths, so it's hard to know / remember to add a route.

Another thing is - our previous routing code wasn't tested at all, so a lot of the previous routing code is removed and covered with tests. I added 225 lines of routing code - covered with tests - but removed 185 lines of code that wasn't tested at all. So it's really only net +40 lines of tested code.

Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

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

Wonderful tests! I went hard into nits for this, but overall this is wonderfully tested and structured code 🥳🥳🥳

"cdr.dev/slog"
)

// Options for configuring a nextrouter
Copy link
Member

Choose a reason for hiding this comment

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

I don't want this to be confused with our primary app routing logic.

For that reason, what do you think about this being in site like it was before? It could even be at the root if you feel that's clean enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I'd prefer to keep it in its own package so it's clear that it is stand-alone - how about I move it to site/nextrouter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved in 19fcfac

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense to me!

@kylecarbs
Copy link
Member

BTW I agree with your comment. It is a bit too sketchy. After reading through the code extensively my POV changed!

Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

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

An absolutely wonderful change!

@bryphe-coder
Copy link
Contributor Author

Thanks for reviewing, @kylecarbs !

@bryphe-coder bryphe-coder merged commit 78bf4c6 into main Feb 9, 2022
@bryphe-coder bryphe-coder deleted the bryphe/feat/nextrouter-pkg branch February 9, 2022 01:01
Comment on lines +44 to +46
nextRouterHandler, err := nextrouter.Handler(filesystem, &nextrouter.Options{
Logger: logger,
TemplateDataFunc: templateFunc,
Copy link
Contributor

Choose a reason for hiding this comment

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

praise: I really like that the nextjs stuff is isolated into a self-contained module.

@@ -0,0 +1,238 @@
package nextrouter
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Can you add a package-level comment about what this module is? It would need to go in nextrouter/doc.go.

See here: https://github.com/coder/m/blob/master/product/coder/pkg/vm/ec2/doc.go

I'm happy to contribute this as my first coder/coder PR if you're ok with that 😂

Copy link
Member

Choose a reason for hiding this comment

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

I like doc.go, but only if we can navigate this repo on https://go.dev. Otherwise it's generally gone unmaintained D:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, that'd be great to contribute @vapurrmaid !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants