Skip to content

Commit 1e86d67

Browse files
committed
api docs improved
1 parent d6a6151 commit 1e86d67

File tree

5 files changed

+274
-51
lines changed

5 files changed

+274
-51
lines changed

docs/API/01-Overview.md

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
# Overview
2+
## Introduction
23

3-
# Introduction
4-
5-
This API is built using [Hono](https://hono.dev/) and serves as a starter kit for building scalable and secure backend applications. It includes authentication, protected routes, rate limiting, and structured routing.
4+
Our API is built using **Hono**, a fast and lightweight web framework designed to handle API requests efficiently. The API adheres to **RESTful principles**, ensuring a consistent and intuitive interface for users. It integrates **Redis** for rate limiting and caching, enhancing performance and preventing abuse. The architecture is structured to be easily extendable and secure.
65

76
## Features
8-
- **Authentication** with middleware
9-
- **Protected routes** for secure endpoints
10-
- **Rate limiting** using Redis
11-
- **RESTful API structure**
12-
- **Support for API clients** (Postman, Fetch API, cURL)
7+
8+
### 1. **Hono Framework**
9+
- **Lightweight and Fast**: Hono is optimized for speed and minimal overhead, making it ideal for serverless environments like Cloudflare Workers.
10+
- **Web Standards Compliance**: Built on web standards, Hono ensures compatibility across different platforms.
11+
12+
### 2. **Protected Routes**
13+
- **Security via Middlewares**: The API uses middlewares to protect routes from unauthorized access. This includes authentication and authorization checks to ensure only authorized users can access sensitive data.
14+
15+
### 3. **Redis-based Rate Limiting**
16+
- **Preventing Abuse**: Redis is used to implement rate limiting, preventing excessive requests from a single source and protecting against potential attacks.
17+
18+
### 4. **Authentication Middleware**
19+
- **Protecting Routes**: Authentication middleware ensures that only authenticated users can access protected routes.
20+
21+
### 5. **Integration with TanStack Query**
22+
- **Efficient Data Fetching and Mutations**: TanStack Query is used to optimize data fetching and mutations, reducing unnecessary requests and improving overall performance.
1323

1424
## Base URL
15-
The API base URL depends on your environment:
1625

17-
- **Development:** `http://localhost:3000/api`
18-
- **Production:** `<your-deployed-url>/api`
26+
The base URL of the API varies depending on the environment:
27+
28+
- **Development**: `http://localhost:3000/api`
29+
- **Production**: `<your-deployed-url>/api`
30+
31+
32+

docs/API/02-Adding-new-endpoint.md

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,78 @@
1-
# Adding new endpoint
1+
# Adding a New Endpoint to the API
22

3-
# New Endpoints
3+
## Overview
44

5-
The API exposes various endpoints for interacting with the backend.
5+
This guide will walk you through adding a new API endpoint using the Hono framework for your server-side application. Follow the steps below to create new routes and handle API requests efficiently.
66

7-
## 1. **Public Endpoints**
8-
### `GET /api/hello`
9-
Returns a simple greeting message.
7+
### Steps to Add a New Endpoint
8+
9+
#### 1. **Navigate to the `routes/api.ts` File**
10+
11+
The primary location for defining your API routes is in the `server/routes/api.ts` file. This is where all core API endpoints should be defined.
12+
13+
#### 2. **Define the New Route**
14+
15+
Use Hono’s routing methods (`app.get`, `app.post`, `app.put`, etc.) to define a new route. Each route corresponds to an HTTP method and a URL pattern.
16+
17+
#### 3. **Implement Logic in the Handler Function**
18+
19+
In the handler function, implement the necessary logic to process the request. You can access request data, query parameters, headers, and more.
20+
21+
#### 4. **Return a JSON Response**
22+
23+
Ensure that your endpoint responds with a JSON object, especially for API responses. Hono's context (`c`) makes it easy to return structured JSON responses.
24+
25+
## Creating a New Router File
26+
27+
If your application grows and you need to organize your routes better, you can create a new file for each module (e.g., routes/users.ts). This can help maintain a clean structure as the project expands.
28+
29+
### Steps to create a new router file
30+
31+
#### 1. **Create a new file**
32+
33+
In the server/routes/ directory. For example, you can create server/routes/users.ts for user-related routes.
34+
35+
#### 2. **Define your routes**
36+
37+
using Hono’s routing methods (app.get, app.post, etc.) in the new file.
38+
39+
#### 3. **Import and use the new router**
40+
41+
in the main server configuration file (e.g., server.ts).
42+
43+
44+
### Example of creating a ` Users ` router
45+
46+
Create a file, `server/routes/users.ts`, where you define routes related to user management:
1047

11-
**Request:**
1248
```ts
13-
app.get('/hello', (c) => {
14-
return c.json({ message: 'Hello from Hono API!' });
49+
import { Hono } from 'hono';
50+
51+
const app = new Hono();
52+
53+
app.get('/api/users', (c) => {
54+
// Logic to retrieve all users
55+
const users = getAllUsers(); // Assume this function fetches user data
56+
return c.json(users); // Return the response as JSON
1557
});
58+
59+
export default app;
60+
```
61+
62+
Then, ensure that the `users.ts` router is imported and used in the main server setup `server.ts`
63+
64+
File: ` server.ts `
65+
66+
```ts
67+
import { Hono } from 'hono';
68+
import users from './routes/users.ts'
69+
70+
const app = new Hono();
71+
72+
app.router('/api/users', users);
73+
74+
export default app;
75+
```
76+
77+
You can also define a router file for defining all the routes and then importing the file in `server.ts`. For more best
78+
practices regarding hono you can refer to their official docs [Hono Best Practices](https://hono.dev/docs/guides/best-practices).

docs/API/03-Protected-routes.md

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
# Protected Routes
22

3-
Some API routes require user authentication to access.
3+
Hono has built-in support for [middlewares](https://hono.dev/docs/guides/middleware), which are functions that can be used to modify the context or execute code before or after a route handler is executed.
44

5-
## Middleware-Based Protection
5+
That's how we can secure our API endpoints from unauthorized access. Below are some examples of you can leverage middlewares to protect your API routes.
66

7-
We use the `authMiddleware` to enforce authentication for specific routes.
7+
## Authenticated access
88

9-
### **Middleware: `authMiddleware`**
9+
After validating the user's authentication status using next-auth, it automatically stores the user data in sessions object. This allows us to access the user's information in subsequent middleware and procedures without having to re-validate the session.
10+
11+
We have already provided with a auth middleware which yo can find at `server/middlewares/auth-middleware.ts` which provides with basic authenticated access.
12+
13+
```ts
14+
import type { Context, Next } from 'hono'
15+
import { auth } from '@/lib/auth'
16+
import { log } from '@/lib/logger'
17+
18+
export const authMiddleware = async (c: Context, next: Next) => {
19+
try {
20+
const session = await auth();
21+
22+
if (!session) {
23+
return c.json({ error: 'Unauthorized' }, 401)
24+
}
25+
26+
c.set('user', session.user) // Attach user data to context
27+
await next()
28+
} catch (err) {
29+
console.error('Error in auth middleware:', err)
30+
log("error", "Error in auth middleware: " + err)
31+
return c.json({ error: 'Internal server error' }, 500)
32+
}
33+
}
34+
```
1035

11-
Located at `src/server/middlewares/auth-middleware.ts`, this middleware ensures that only authenticated users can access protected routes.
1236

1337
### **Applying Middleware**
1438

@@ -19,3 +43,39 @@ app.get("/protected", authMiddleware, (c) => {
1943
const user: any = c.get("user");
2044
return c.json({ message: "Protected API Data", name: user.name });
2145
});
46+
```
47+
48+
## Feature-based access
49+
50+
To implement feature-based access, such as role-based access control (RBAC), you can define a middleware that checks the user's role before allowing access to certain routes.
51+
52+
Here's an example of how you can create a role-based access middleware:
53+
54+
```ts
55+
import type { Context, Next } from 'hono'
56+
57+
export const roleMiddleware = (requiredRole: string) => {
58+
return async (c: Context, next: Next) => {
59+
const user: any = c.get('user')
60+
61+
if (!user || user.role !== requiredRole) {
62+
return c.json({ error: 'Forbidden' }, 403)
63+
}
64+
65+
await next()
66+
}
67+
}
68+
```
69+
70+
### **Applying Role-Based Middleware**
71+
72+
To apply role-based access control to an endpoint, attach `roleMiddleware` with the required role to the route definition:
73+
74+
```ts
75+
app.get("/admin", authMiddleware, roleMiddleware('admin'), (c) => {
76+
return c.json({ message: "Admin API Data" });
77+
});
78+
```
79+
80+
In this example, only users with the role `admin` will be able to access the `/admin` route.
81+

docs/API/04-Using-API-client.md

Lines changed: 112 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Using Api Client
22

3-
This app supports various HTTP methods, and all requests are handled in `src/app/api/[...routes]/route.tsx`.
3+
This app supports various HTTP methods, and all requests are handled in `src/app/api/[...routes]/route.tsx`. It exports all the related HTTP methods so you only need to make the api call using your preferred method and you are good to go.
44

55
## Available Methods
66
```ts
@@ -12,21 +12,123 @@ export const PATCH = handle(app);
1212
export const OPTIONS = handle(app);
1313
```
1414

15+
Each exported method is responsible for handling the corresponding HTTP request and routing it to the appropriate logic within the app.
16+
1517
## Example GET Request using TanStack Query
1618

17-
To call a GET request using TanStack Query, you can use the `useQuery` hook as shown below:
19+
TanStack Query is a powerful library for managing server state in React applications. You can use it to call API endpoints like the one you’ve defined in your route.tsx file.
20+
21+
Using TanStack Query in combination with your Hono API client allows you to manage server-state in a declarative way while handling various HTTP methods such as GET, POST, PUT, DELETE, and PATCH. By leveraging TanStack Query, It can simplify state management, automatically handle caching and refetching.
22+
23+
Here’s how you can perform a GET request to fetch data using TanStack Query:
1824

1925
```ts
2026
import { useQuery } from '@tanstack/react-query';
2127

2228
const fetchHello = async () => {
23-
const res = await fetch("/api/hello");
24-
if (!res.ok) throw new Error("Failed to fetch data");
25-
return res.json();
26-
};
29+
const res = await fetch("/api/hello");
30+
if (!res.ok) {
31+
throw new Error("Failed to fetch data");
32+
}
33+
return res.json();
34+
};
2735

28-
const { data: helloData } = useQuery({
36+
const HelloComponent = () => {
37+
const { data: helloData, error, isLoading } = useQuery({
2938
queryKey: ["hello"],
30-
queryFn: fetchHello,
31-
});
32-
```
39+
queryFn: fetchHello,
40+
});
41+
42+
if (isLoading) {
43+
return <div>Loading...</div>;
44+
}
45+
46+
if (error instanceof Error) {
47+
return <div>Error: {error.message}</div>;
48+
}
49+
return <div>{helloData?.message}</div>;
50+
};
51+
52+
export default HelloComponent;
53+
54+
```
55+
## Handling POST, PUT, DELETE Requests with TanStack Query
56+
57+
Just like with GET requests, you can also use TanStack Query for making POST, PUT, DELETE, or PATCH requests to your API. Below are some examples of how to handle these HTTP methods.
58+
59+
### Example: Making a POST Request
60+
61+
For sending data (e.g., creating a new resource), use the `mutate` function from the `useMutation` hook:
62+
63+
```ts
64+
import { useMutation } from '@tanstack/react-query';
65+
66+
const createUser = async (userData: { name: string }) => {
67+
const res = await fetch("/api/users", {
68+
method: "POST",
69+
headers: {
70+
"Content-Type": "application/json",
71+
},
72+
body: JSON.stringify(userData),
73+
});
74+
75+
if (!res.ok) throw new Error("Failed to create user");
76+
return res.json();
77+
};
78+
79+
const UserCreationComponent = () => {
80+
const mutation = useMutation({
81+
mutationFn: createUser,
82+
});
83+
84+
const handleCreateUser = () => {
85+
const newUser = { name: "John Doe" };
86+
mutation.mutate(newUser);
87+
};
88+
89+
return (
90+
<div>
91+
<button onClick={handleCreateUser}>Create User</button>
92+
{mutation.isLoading && <div>Creating user...</div>}
93+
{mutation.isError && <div>Error: {mutation.error.message}</div>}
94+
{mutation.isSuccess && <div>User created successfully!</div>}
95+
</div>
96+
);
97+
};
98+
99+
export default UserCreationComponent;
100+
```
101+
102+
### Example: Making a PUT Request
103+
104+
For updating a resource:
105+
106+
```ts
107+
const updateUser = async (userId: string, userData: { name: string }) => {
108+
const res = await fetch(`/api/users/${userId}`, {
109+
method: "PUT",
110+
headers: {
111+
"Content-Type": "application/json",
112+
},
113+
body: JSON.stringify(userData),
114+
});
115+
116+
if (!res.ok) throw new Error("Failed to update user");
117+
return res.json();
118+
};
119+
```
120+
121+
### Example: Making a DELETE Request
122+
123+
For deleting a resource:
124+
125+
```ts
126+
const deleteUser = async (userId: string) => {
127+
const res = await fetch(`/api/users/${userId}`, {
128+
method: "DELETE",
129+
});
130+
131+
if (!res.ok) throw new Error("Failed to delete user");
132+
return res.json();
133+
};
134+
```

docs/API/05-Mutations.md

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)