hapijs / inert

Static file and directory handlers for hapi.js
Other
237 stars 49 forks source link

Add h.directory() toolkit decoration #155

Open devinivy opened 3 years ago

devinivy commented 3 years ago

Support plan

Context

What problem are you trying to solve?

We would like to serve a directory (a la the directory handler-type) which is determined asynchronously. The current solution is to define a synchronous path config for the directory handler-type, but compute the path in a pre-handler. This creates some indirection that we don't see with the file handler-type due to the existence of h.file().

Do you have a new or modified API suggestion to solve the problem?

The recommendation coming from conversation in #154 is to introduce a new toolkit decoration h.directory() that can be called in a standard handler, with arbitrary logic preceding it within the handler. The input to h.directory() would mirror the input to the directory handler-type, analogously to h.file() and the file handler-type.

server.route({
    method: 'get',
    path: '/dir/{file*}',
    handler : async (request, h) => {

        const myDependencyFile = await import.meta.resolve('my-dependency');

        return h.directory(path.dirname(myDependencyFile), {
            listing: true,
            redirectToSlash: true
        });
    }
});
kanongil commented 3 years ago

I am not a fan of this feature, but this is mainly a performance / implementation complexity concern. The mentioned use-case already has a high-performing solution, so I would be disinclined to add this on the basis of that only.

The issue is validation and massaging of the options. Running a full schema validation on each invocation is prohibitively expensive. The alternative solution, which is used for the file handler, is to not use the full schema validation, but a custom simpler validation. However this requires a lot of care to get right, and makes the code / interface more brittle.

kanongil commented 2 years ago

Given that the options passed to h.directory are probably quite static, the above issue could be fixed by exposing a method to prevalidate them, and allow (or require) the options to be the return value of this pre-validation.