Lightweight, Minimalist Framework For REST API ๐ฆ ๐
Hello! Thank you for checking out Denorest!
To create a very basic โhello, Deno!โ server, you would want to create a server.ts
file with the
following
content:
import { WebApp, Router, Req, Res } from "https://deno.land/x/denorest@v3.1/mod.ts";
const app = new WebApp();
const router = new Router();
router.get("/", (_req: Req, res: Res) => {
res.reply = "Hello, Deno!";
});
app.set(router);
app.listen(8080);
And then you would run the following command:
$ deno run --allow-net server.ts
If you arenโt overly familiar with Deno, by default it does not trust the code you are running, and need you to let it have access to your machines network, so --allow-net provides that.
When navigating on your local machine to http://localhost:8080/ you should see the Hello world! message in your browser.
Use the Router class to create modular, mountable route handlers.
The following example creates a router as a module, defines some routes, and assign router using
WebApp.set()
function.
import { Req, Res, Router, WebApp } from "https://deno.land/x/denorest@v3.1/mod.ts";
const app = new WebApp();
// create router
const router = new Router();
// define the home page route
router.get("/", (_req: Req, res: Res) => {
res.reply = {
page: "Home",
};
});
// define the about page route
router.get("/about", (_req: Req, res: Res) => {
res.reply = {
page: "About",
};
});
// assign router
app.set(router);
app.listen(8080);
A route method is derived from one of the HTTP methods, and is attached to an instance of the
Router
class.
The following code is an example of routes that are defined for the GET and the POST methods to the router module.
// GET method route
router.get("/", (req: Req, res: Res) => {
res.reply = {
page: "Home",
method: "GET",
};
});
// POST method route
router.post("/", (req: Req, res: Res) => {
res.reply = {
page: "Home",
method: "POST",
};
});
There is a special routing method Router.all()
, used to load route functions at a path for all
HTTP request
methods. For example, the following handler is executed for requests to the route /about
whether
using GET,
POST, PUT, DELETE, or any other HTTP request method supported in the http module.
router.all("/about", (_req: Req, res: Res) => {
res.reply = {
page: "About",
};
});
Create a router file named birds.ts
in the app directory, with the following content:
import { Router, Req, Res } from "https://deno.land/x/denorest@v3.1/mod.ts";
// create router
const router = new Router();
// define the home page route
router.all("/", (req: Req, res: Res) => {
res.reply = {
page: "Birds Home",
};
});
// define the about page route
router.all("/about", (req: Req, res: Res) => {
res.reply = {
page: "Birds About",
};
});
export default router;
Then, load the router module in the app using Router.pre()
function:
// ...
import birdRouter from "./birds.ts";
// ...
router.pre("/birds", birdRouter);
// assign router
app.set(router);
// ...
The app will now be able to handle requests to /birds
and /birds/about
Middleware functions are functions that have access to the request object (Req) and response object (Res),
Bind middleware using Router.use()
function.
// ...
// create router
const router = new Router();
// define middleware
router.use((req: Req, res: Res) => {
// ...
if (auth) {
req.state.auth = true;
} else {
res.reply = {
massage: "Please login",
};
}
})
// define the home page route
router.all("/", (req: Req, res: Res) => {
// ...
res.reply = {
page: "Birds Home",
};
});
// ...
Use middleware in specific route using route handler third parameter.
// ...
// middleware
const auth = (req: Req, res: Res) => {
// ...
if (auth) {
req.state.auth = true;
} else {
res.reply = {
massage: "Please login",
};
}
}
// define the home page route
router.all("/", (req: Req, res: Res) => {
// ...
});
// define the about page route
router.all("/about", (req: Req, res: Res) => {
res.reply = {
page: "Birds About",
};
}, [auth, ...]); // assign middleware in third parameter
// ...
The first parameter of the handler function is Req
.
Req is a containing the following fields:
.body
The request payload.
.headers
The headers of the incoming request.
.method
The method of the incoming request.
.url
The URL of the incoming request.
.reg
The RegExp of the current route.
.state
Store state for routing. Type:
Record<string | number, string | number | boolean>
The second parameter of the handler function is Res
.
Res is a containing the following fields:
.reply
Sends the payload to the user, could be a plain text, or
BodyInit
.
.headers
Sets all the keys of the object as response headers.
.status
Sets the status code.
Set default headers for all routes using WebApp.headers()
function.
// ...
const app = new WebApp();
app.headers({
"Content-Type": "text/html"
})
// ...
Route parameters are named URL segments that are used to capture the values specified at their position in the URL.
import { Req, Res, Router, WebApp, pathParse } from "https://deno.land/x/denorest@v3.1/mod.ts";
// ...
router.all("/:username/post/:postId", (req: Req, res: Res) => {
// using pathParse() function
const path = pathParse(req);
console.log(path);
res.reply = {
username: path.params.username,
post_id: path.params.postId
};
});
// ...
Route path: /:username/post/:postId
Request URL: http://localhost:8080/deno/post/12?page=2
pathParse(Req): { params: { username: "deno", postId: "12" }, query: { page: "2" } }
Support Content-Type:
import { Req, Res, Router, WebApp, bodyParse } from "https://deno.land/x/denorest@v3.1/mod.ts";
// ...
router.post("/", async (req: Req, res: Res) => {
// using bodyParse() function
const body = await bodyParse(req);
console.log(body);
res.reply = {
page: "Home"
};
});
// ...
You can handle 404 and 500 response using WebApp.set404()
and WebApp.set500()
function.
// ...
// set 404 route
app.set404(async (req: any, res: any) => {
res.status = 404;
res.headers = {
"Content-Type": "text/html",
};
res.reply = "Not Found";
});
// set 500 route
app.set500(async (req: any, res: any) => {
res.status = 500;
res.headers = {
"Content-Type": "text/html",
};
res.reply = "Internal Server Error";
});
// ...
HTTPS is supported in all modern browsers.
import { WebApp, Router, Req, Res } from "https://deno.land/x/denorest@v3.1/mod.ts";
const app = new WebApp();
const router = new Router();
router.get("/", (_req: Req, res: Res) => {
res.reply = "Hello, Deno!";
});
app.set(router);
app.listenTls(443, "./cert.pem", "./key.pem");
If you'd like to contribute, start by searching through the issues and pull requests to see whether someone else has raised a similar idea or question.
If you don't see your idea listed, and you think it fits into the goals of this guide, do one of the following: