8000 feat: nextrouter pkg to handle nextjs routing rules by bryphe-coder · Pull Request #167 · coder/coder · GitHub
[go: up one dir, main page]

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
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
dd6d315
Add in-memory fs example
bryphe-coder Feb 5, 2022
33897e5
Integrate test server too
bryphe-coder Feb 5, 2022
b8d092c
Some initial test cases for files at root
bryphe-coder Feb 5, 2022
9949261
Serve contents from filesystem
bryphe-coder Feb 5, 2022
fadc0b6
Factor router out
bryphe-coder Feb 5, 2022
771f39d
Add recursive router building
bryphe-coder Feb 5, 2022
78406b1
Hook up recursive case
bryphe-coder Feb 5, 2022
50c72ba
Refactor to handle different file-serving cases
bryphe-coder Feb 5, 2022
7a98a48
Handle case w/o html extension
bryphe-coder Feb 5, 2022
1eb2402
Handle redirecting to index.html at root
bryphe-coder Feb 5, 2022
b0fd9a8
Add test case for nested path
bryphe-coder Feb 5, 2022
a506148
Remove now-unnecessary smoke test
bryphe-coder Feb 5, 2022
b59e2a8
Some clean up
bryphe-coder Feb 5, 2022
ff75695
Refactor to use http.ServeContent
bryphe-coder Feb 5, 2022
a410396
Simplify router construction
bryphe-coder Feb 5, 2022
15c38b9
rtr -> router
bryphe-coder Feb 5, 2022
c813b5e
Handle serving non-html files
bryphe-coder Feb 5, 2022
317c040
Handle trailing-slash case
bryphe-coder Feb 5, 2022
133e452
Implement dynamic routing
bryphe-coder Feb 5, 2022
6d8f412
Add test case to verify static paths are preferred over dynamic paths
bryphe-coder Feb 5, 2022
a3ecd7f
Handle dynamic routing for folders
bryphe-coder Feb 5, 2022
700c9ef
Handle catch-all routes
bryphe-coder Feb 5, 2022
05a369e
Start plumbing in a way to inject template parameters
bryphe-coder Feb 5, 2022
03a20c1
Start adding plumbing for templates
bryphe-coder Feb 5, 2022
199d468
Add template functionality
bryphe-coder Feb 5, 2022
ca515e4
Set up 404 handling
bryphe-coder Feb 5, 2022
6072bad
Use nextrouter package in site, which simplifies it quite a bit
bryphe-coder Feb 5, 2022
826eaf5
Update interface to take logger
bryphe-coder Feb 5, 2022
dac34f5
Additional comments
bryphe-coder Feb 5, 2022
92d4eb0
Fix embed_test
bryphe-coder Feb 5, 2022
5262b7f
Remove now-unused noop template func
bryphe-coder Feb 5, 2022
33342e5
Merge main
bryphe-coder Feb 8, 2022
750bec9
Switch route addition from info -> debug log level
bryphe-coder Feb 8, 2022
c15b046
Invert logic to remove layer of indentation
bryphe-coder Feb 8, 2022
c17fc15
Rename buildRoutes -> registerRoutes
bryphe-coder Feb 8, 2022
34e4f46
TemplateDataFunc -> HTMLTemplateHandler
bryphe-coder Feb 8, 2022
0743503
Add return to reduce indentation in serveFile
bryphe-coder Feb 8, 2022
4585c13
Remove call to remove file extension
bryphe-coder Feb 8, 2022
8f2b47d
Switch to register 404, return error and warn at toplevel
bryphe-coder Feb 8, 2022
19fcfac
Move ./nextrouter -> ./site/nextrouter
bryphe-coder Feb 8, 2022
8343923
Return error from handler
bryphe-coder Feb 8, 2022
4a5c353
Change dynamic route logging from Info -> Debug
bryphe-coder Feb 8, 2022
e4d031f
Merge main
bryphe-coder Feb 9, 2022
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
Prev Previous commit
Next Next commit
Return error from handler
  • Loading branch information
bryphe-coder committed Feb 8, 2022
commit 834392361144fd5b4e06a53c5fb42c5e565f7081
7 changes: 6 additions & 1 deletion site/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@ func Handler(logger slog.Logger) http.Handler {
}
}

nextRouterHandler := nextrouter.Handler(filesystem, &nextrouter.Options{
nextRouterHandler, err := nextrouter.Handler(filesystem, &nextrouter.Options{
Logger: logger,
TemplateDataFunc: templateFunc,
})
if err != nil {
// There was an error setting up our file system handler.
// This likely means a problem with our embedded file system.
panic(err)
}
return secureHeaders(nextRouterHandler)
}

Expand Down
28 changes: 17 additions & 11 deletions site/nextrouter/nextrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type HTMLTemplateHandler func(*http.Request) interface{}
//
// 1) If a file is of the form `[org]`, it's a dynamic route for a single-parameter
// 2) If a file is of the form `[[...any]]`, it's a dynamic route for any parameters
func Handler(fileSystem fs.FS, options *Options) http.Handler {
func Handler(fileSystem fs.FS, options *Options) (http.Handler, error) {
if options == nil {
options = &Options{
Logger: slog.Logger{},
Expand All @@ -43,7 +43,10 @@ func Handler(fileSystem fs.FS, options *Options) http.Handler {
router := chi.NewRouter()

// Build up a router that matches NextJS routing rules, for HTML files
registerRoutes(router, fileSystem, *options)
err := registerRoutes(router, fileSystem, *options)
if err != nil {
return nil, err
}

// Fallback to static file server for non-HTML files
// Non-HTML files don't have special routing rules, so we can just leverage
Expand All @@ -52,22 +55,21 @@ func Handler(fileSystem fs.FS, options *Options) http.Handler {
router.NotFound(fileHandler.ServeHTTP)

// Finally, if there is a 404.html available, serve that
err := register404(fileSystem, router, *options)
if (err != nil) {
err = register404(fileSystem, router, *options)
if err != nil {
// An error may be expected if a 404.html is not present
options.Logger.Warn(context.Background(), "Unable to find 404.html", slog.Error(err))
}

return router
return router, nil
}

// registerRoutes recursively traverses the file-system, building routes
// as appropriate for respecting NextJS dynamic rules.
func registerRoutes(rtr chi.Router, fileSystem fs.FS, options Options) {
func registerRoutes(rtr chi.Router, fileSystem fs.FS, options Options) error {
files, err := fs.ReadDir(fileSystem, ".")
if err != nil {
options.Logger.Warn(context.Background(), "Provided filesystem is empty; unable to build routes")
return
return err
}

// Loop through everything in the current directory...
Expand All @@ -84,8 +86,7 @@ func registerRoutes(rtr chi.Router, fileSystem fs.FS, options Options) {
// recursively calling `buildRouter`
sub, err := fs.Sub(fileSystem, name)
if err != nil {
options.Logger.Error(context.Background(), "Unable to call fs.Sub on directory", slog.F("directory_name", name))
continue
return err
}

// In the special case where the folder is dynamic,
Expand All @@ -98,9 +99,14 @@ func registerRoutes(rtr chi.Router, fileSystem fs.FS, options Options) {

options.Logger.Debug(context.Background(), "Registering route", slog.F("name", name), slog.F("routeName", routeName))
rtr.Route("/"+routeName, func(r chi.Router) {
registerRoutes(r, sub, options)
err := registerRoutes(r, sub, options)
if err != nil {
options.Logger.Error(context.Background(), "Error registering route", slog.F("name", routeName), slog.Error(err))
}
})
}

return nil
}

// serveFile is responsible for serving up HTML files in our next router
Expand Down
45 changes: 30 additions & 15 deletions site/nextrouter/nextrouter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("test.html", []byte("test123"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test.html")
Expand All @@ -46,7 +47,8 @@ func TestNextRouter(t *testing.T) {
err = rootFS.WriteFile("folder.html", []byte("folderFile"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/folder/")
Expand All @@ -65,7 +67,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("test.png", []byte("png-bytes"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test.png")
Expand All @@ -85,7 +88,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("test.html", []byte("test-no-extension"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test")
Expand All @@ -104,7 +108,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("index.html", []byte("test-root-index"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/")
Expand All @@ -128,7 +133,8 @@ func TestNextRouter(t *testing.T) {
rootFS.WriteFile("test/a/b/c.html", []byte("test123"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test/a/b/c.html")
Expand All @@ -155,7 +161,8 @@ func TestNextRouter(t *testing.T) {
rootFS.WriteFile("test/a/b/c/index.html", []byte("test-abc-index"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test/a/b/c")
Expand All @@ -175,7 +182,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("test.html", []byte("test123"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test-non-existent.html")
Expand All @@ -191,7 +199,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("test.html", []byte("test123"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test-non-existent.html")
Expand All @@ -207,7 +216,8 @@ func TestNextRouter(t *testing.T) {
err := rootFS.WriteFile("404.html", []byte("404 custom content"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test-non-existent.html")
Expand All @@ -227,7 +237,8 @@ func TestNextRouter(t *testing.T) {
err = rootFS.WriteFile("folder/[orgs].html", []byte("test-dynamic-path"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/folder/org-1")
Expand All @@ -248,7 +259,8 @@ func TestNextRouter(t *testing.T) {
err = rootFS.WriteFile("folder/[org]/[project]/create.html", []byte("test-create"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/folder/org-1/project-1/create")
Expand All @@ -269,7 +281,8 @@ func TestNextRouter(t *testing.T) {
err = rootFS.WriteFile("folder/[[...any]].html", []byte("test-catch-all"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/folder/org-1/project-1/random")
Expand All @@ -292,7 +305,8 @@ func TestNextRouter(t *testing.T) {
err = rootFS.WriteFile("folder/create.html", []byte("test-create"), 0755)
require.NoError(t, err)

router := nextrouter.Handler(rootFS, nil)
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/folder/create")
Expand Down Expand Up @@ -329,10 +343,11 @@ func TestNextRouter(t *testing.T) {
}
}

router := nextrouter.Handler(rootFS, &nextrouter.Options{
router, err := nextrouter.Handler(rootFS, &nextrouter.Options{
Logger: slog.Logger{},
TemplateDataFunc: templateFunc,
})
require.NoError(t, err)
server := httptest.NewServer(router)

res, err := request(server, "/test.html")
Expand Down
0