std/http: Provide classes for common HTTP response status codes
See original GitHub issueIs your feature request related to a problem? Please describe.
When building a web application, it’s very common to have to re-use the same HTTP responses when handling errors. Applications that do a lot of input-validation might find it annoying to have to redeclare the proper HTTP responses. Others might find it annoying that there is no “proper” way of handling errors.
import { serve } from "https://deno.land/std/http/server.ts";
serve(req => {
if (!validateRequest(req)) return new Response("Did not pass validation", { status: 400, statusCode: "Bad Request" });
if (!pathExists(req)) return new Response("404 Not Found", { status: 404, statusCode: "404 Not Found" });
if (shouldRedirect(req)) return new Response(undefined, { status: 308, location: "https://www.example.com" });
return new Response("Hello world"));
}
Describe the solution you’d like
We could add classes for common HTTP status responses to the std/http
module.
These classes would include a default message, such as 404 Not Found
, and would return the correct status code and text.
This would remove some boilerplate from any project that makes use of the Response
class, such as projects using Deno.serveHttp()
or the std/http
server.
import { serve } from "https://deno.land/std/http/server.ts";
import {
BadRequestResponse,
NotFoundResponse,
PermanentRedirectResponse,
} from "https://deno.land/std/http/responses.ts";
serve(req => {
if (!validateRequest(req)) return new BadRequestResponse("Did not pass validation");
if (!pathExists(req)) return new NotFoundResponse();
if (shouldRedirect(req)) return new PermanentRedirectResponse("https://www.example.com");
return new Response("Hello world"));
}
Example implementation (API doesn’t have to be this, it’s just an example): std/http/response.ts:
// The class should extend the `Response` class, so that
// `new NotFoundResponse() instanceof Response` returns `true`.
export class NotFoundResponse extends Response {
constructor(body: BodyInit = "404 Not Found", init: ResponseInit = {}) {
super(body, {
...init,
status: 404,
statusText: "Not Found",
});
}
}
// This class is a bit more opinionated, but is still very generic.
class PermanentRedirectResponse extends Response {
constructor(location: string) {
super(undefined, {
status: 308,
statusText: "Permanent Redirect",
headers: { location },
});
}
}
Describe alternatives you’ve considered
Because this suggestion is not hard to implement, the alternative would be to let programmers build it themselves.
However, because this is a fairly straightforward suggestion and because it could benefit any project, I think it would do no harm to add it to the std/http
module.
Any feedback is welcomed.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:5
- Comments:5 (5 by maintainers)
I like this and have been wishing for something like it several times.
In other languages and frameworks, I have seen that “preset / factory” pattern exposed as static functions (not as a clnstructor) like that:
But that is a small stylistic decision, it’s just less prototypes and a tiny bit less verbose. I don’t even know if that is possible to do reasonably though, with
Response
being provided by the runtime.A design note: I think the names should match up exactly with the
Status
enum names, so much that for codes with no special logic, it could be auto-generated.A way to manage this could be to create an umbrella issue with API drafts and discuss those - there are a lot of overall and tiny API decisions to be made if we want to do this (e.g. what is required and what isn’t? Do we force our users to adhere to the spec? Options object for everything or positionals and options depending on the status?).
For me personally, “framework” means opinionated, specific, locked-in (which does not necessarily mean that we should not do it -
std/http
being a viable option to write an application is at least my goal). For me, this seems more like a utility to solve something that happens in pretty much all use cases in a more spec compliant way.