JavaScript Development Space

Meet Hono - A Lightweight Backend Framework for Cloud-Native Applications

Add to your RSS feedSeptember, 5th 20245 min read
Meet Hono - A Lightweight Backend Framework for Cloud-Native Applications

Hono is a cutting-edge, lightweight backend framework designed for cloud-native applications. Built on Node.js, Hono is optimized for speed and scalability, making it perfect for building high-performance APIs and services. Its minimalistic design allows developers to quickly create efficient, scalable solutions for modern cloud environments. Hono also offers support for edge computing, middleware, and routing, making it an excellent choice for developers looking to build cloud-native applications with minimal overhead and maximum performance.

Create a simple Backend

We will use Bun - an another JavaScript runtime, and Node.js-compatible package manager. If you are not familiar with Bun, please read this article.

1. Install Hono

bun create hono hono-demo
bash
1 ✔ Using target directory … hono-demo
2 ? Which template do you want to use? bun
3 ? Do you want to install project dependencies? yes
4 ? Which package manager do you want to use? bun
5 ✔ Cloning the template
6 ✔ Installing project dependencies
7 🎉 Copied project files
8 Get started with: cd hono-demo

Move to hono-demo

cd hono-demo

Install dependencies

bun install

2. Run the Hono app

Change the default port

js
1 // index.ts
2
3 import { Hono } from 'hono';
4
5 const app = new Hono();
6
7 app.get('/', (c) => {
8 return c.text('Hello Hono!');
9 });
10
11 export default {
12 port: 4200,
13 fetch: app.fetch,
14 };

Run the app

bun dev

Result:

bash
1 $ bun run --hot src/index.ts
2 Started server http://localhost:4200

Now the HTTP requests coming to the Bun server will be handled by Hono framework, providing us with a much more convenient API.

3. Grouped Routing in Hono.JS

According to the official Hono documentation, the framework supports grouped routing, allowing you to organize routes using an instance of Hono and add them to the main application using the route method.

Let’s create a post.ts inside a routes folder. Don’t forget to export posts as the default export:

ts
1 // routes/post.ts
2
3 import { Hono } from 'hono';
4
5 const post = new Hono();
6
7 post.get('/', (c) => c.text('List Posts')); // GET /post
8 post.get('/:id', (c) => {
9 // GET /post/:id
10 const id = c.req.param('id');
11 return c.text('Get Post: ' + id);
12 });
13 post.post('/', (c) => c.text('Create Book')); // POST /post
14
15 export default post;

Open Postman and navigate to http://localhost:4200/post/2 to test it

Hono backend Postman

4. So, what exactly is the "c" in the arguments?

However, you might have noticed that c is used instead of req. This c stands for the context object, as detailed in the Hono.js documentation.

In practice, all incoming and outgoing data is managed by this context object. Hono allows you to return responses in various formats, not just JSON but also others, such as body, text, notFound, redirect and more.

Hono is also well-suited for handling and returning small amounts of HTML.

5. Rendering TSX/JSX

Although hono/jsx is typically used on the client side, it can also be utilized for server-side content rendering.

In the JSX section, there’s an example of a functional React component. Let’s try rendering it server-side:

Create a post page inside a pages folder:

tsx
1 // pages/post.tsx
2
3 import { FC, PropsWithChildren } from 'hono/jsx';
4
5 type PostData = {
6 title: string;
7 id: string;
8 };
9
10 const Layout: FC = ({ children }: PropsWithChildren) => {
11 return (
12 <html>
13 <body>{children}</body>
14 </html>
15 );
16 };
17
18 const PostComponent = ({ title, id }: PostData) => {
19 return (
20 <Layout>
21 <h1>Hello {title}</h1>
22 <p>Your id is {id}</p>
23 </Layout>
24 );
25 };
26
27 export default PostComponent;

Now Let’s connect it to our post route:

tsx
1 // routes/post.tsx
2
3 post.get('/:id', (c) => {
4 // GET /book/:id
5 const id = c.req.param('id');
6 return c.html(<PostComponent id={id} title={' World!'} />);
7 });

Open http://localhost:4200/post/2 in your browser to test it.

This approach is similar to SSR in Next.js or Remix.js, but it's much lighter. Hono also supports other features like asynchronous components, Suspense, and more.

6. Middleware

Middleware is a function that integrates into the routing process and performs various operations.

You can intercept a request before it's processed or modify a response before it's sent.

HonoJS has a lot of built-in middleware, and you can add your own or reuse middleware created by the community.

Let's take a look at the official example from the documentation.

Add this code to index.ts file, before routes initialization

ts
1 app.use(async (c, next) => {
2 const start = Date.now();
3 await next();
4 const end = Date.now();
5 c.res.headers.set('X-Response-Time', `${end - start}`);
6 });

Check the result in Postman

Postman response

7. Handling redirects

You can create a redirect using the c.redirect() method:

ts
1 c.redirect('/go-there');
2 c.redirect('/go-there', 301);

8. Handling CORS

To enable our application to work with a frontend framework, we need to implement CORS. Hono offers a cors middleware for this purpose. Import and configure this middleware in your index.ts file:

ts
1 import { cors } from 'hono/cors';
2 app.use('/api/*', cors());

9. Testing

Create index.test.ts file:

ts
1 import { expect, test, describe } from 'bun:test';
2 import { Hono } from 'hono';
3 import { testClient } from 'hono/testing';
4
5 describe('Example', async () => {
6 const app = new Hono().get('/', (c) => c.json('Hello Hono!'));
7 const res = await testClient(app).$get();
8 test('GET /post', async () => {
9 const res = await app.request('/');
10 expect(res.status).toBe(200);
11 expect(await res.json()).toEqual('Hello Hono!');
12 });
13 });

Now run

bun test
bash
1 bun test v1.1.26 (0a37423b)
2
3 src\index.test.ts:
4 ✓ Example > GET /post
5
6 1 pass
7 0 fail
8 2 expect() calls
9 Ran 1 tests across 1 files. [301.00ms]

Conclusion

Creating a simple backend with Hono is both straightforward and efficient. With its lightweight design and built-in features, Hono allows you to quickly set up a server capable of handling a variety of tasks, from routing to middleware integration. By leveraging Hono's powerful capabilities, such as built-in support for CORS and flexible response formats, you can build robust backend solutions with minimal effort. Whether you’re developing a small-scale application or experimenting with new ideas, Hono provides the tools you need to get your project up and running smoothly.

Related Posts:

Download Images From Instagram Using NodeJS and Puppeteer

Learn how to harness the power of Google Puppeteer to automate the process of downloading images from Instagram.

JavaScript Development Space

Follow JavaScript Development Space

Stay updated with the latest trends, tutorials, and best practices in JavaScript development. Follow our JavaScript Development blog for expert insights, coding tips, and resources to enhance your web development skills.

© 2024 JavaScript Development Blog. All rights reserved.