在 Web 开发中,RESTful API 是一种常见的设计风格,它可以帮助我们构建可扩展、易于维护的应用程序。Hapi 是一个基于 Node.js 的 Web 框架,它提供了一些强大的工具和功能,使得我们可以很容易地创建 RESTful API。
在本文中,我们将介绍如何使用 Hapi 框架来实现 RESTful API CRUD 操作。我们将从基础的路由和控制器开始,逐步构建一个完整的 API,并提供一些示例代码和指导意义。
基础的路由和控制器
在 Hapi 中,我们可以使用 server.route()
方法来定义路由。一个基本的路由定义如下:
server.route({ method: 'GET', path: '/', handler: (request, h) => { return 'Hello, world!'; } });
这个路由定义了一个 GET 请求,路径为 /
,返回一个字符串 'Hello, world!'
。
在一个 RESTful API 中,我们通常会使用四个 HTTP 方法来执行 CRUD 操作:GET、POST、PUT 和 DELETE。我们可以使用类似上面的方式来定义这些路由。例如,这是一个 GET 请求的示例:
// javascriptcn.com 代码示例 server.route({ method: 'GET', path: '/users/{id}', handler: (request, h) => { const userId = request.params.id; // 查询用户信息 return { id: userId, name: '张三', age: 18 }; } });
这个路由定义了一个 GET 请求,路径为 /users/{id}
,其中 {id}
表示一个动态的参数,我们可以通过 request.params.id
来获取它的值。在这个示例中,我们返回了一个包含用户信息的对象。
控制器是我们处理请求的核心代码。在 Hapi 中,我们通常会将控制器定义为一个函数,它接收请求和响应对象作为参数,然后执行一些逻辑,最后返回一个响应数据。例如,这是一个查询用户信息的控制器:
// javascriptcn.com 代码示例 const getUserById = async (request, h) => { const userId = request.params.id; // 查询用户信息 const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); if (!user) { throw Boom.notFound('User not found'); } return user; };
在这个控制器中,我们使用了一个 db
对象来查询数据库中的用户信息,然后根据查询结果返回响应数据。如果查询结果为空,我们使用 Boom.notFound()
方法来抛出一个 404 错误。
构建完整的 RESTful API
现在,我们已经了解了如何定义路由和控制器,接下来我们将逐步构建一个完整的 RESTful API。我们将以用户信息为例,实现以下四个操作:
- 查询用户列表(GET /users)
- 查询单个用户信息(GET /users/{id})
- 创建用户信息(POST /users)
- 更新用户信息(PUT /users/{id})
- 删除用户信息(DELETE /users/{id})
查询用户列表
首先,我们需要定义一个 GET 请求,用于查询用户列表。这个请求不需要任何参数,直接返回用户列表即可。我们可以使用类似下面的代码来定义路由和控制器:
// javascriptcn.com 代码示例 server.route({ method: 'GET', path: '/users', handler: async (request, h) => { const users = await db.query('SELECT * FROM users'); return users; } }); const getUsers = async (request, h) => { const users = await db.query('SELECT * FROM users'); return users; };
查询单个用户信息
接下来,我们需要定义一个 GET 请求,用于查询单个用户的信息。这个请求需要一个动态参数 id
,表示要查询的用户 ID。我们可以使用类似下面的代码来定义路由和控制器:
// javascriptcn.com 代码示例 server.route({ method: 'GET', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); if (!user) { throw Boom.notFound('User not found'); } return user; } }); const getUserById = async (request, h) => { const userId = request.params.id; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); if (!user) { throw Boom.notFound('User not found'); } return user; };
创建用户信息
接下来,我们需要定义一个 POST 请求,用于创建用户信息。这个请求需要一个 JSON 格式的请求体,包含要创建的用户信息。我们可以使用类似下面的代码来定义路由和控制器:
// javascriptcn.com 代码示例 server.route({ method: 'POST', path: '/users', handler: async (request, h) => { const { name, age } = request.payload; const result = await db.query('INSERT INTO users (name, age) VALUES (?, ?)', [name, age]); const userId = result.insertId; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return h.response(user).code(201); } }); const createUser = async (request, h) => { const { name, age } = request.payload; const result = await db.query('INSERT INTO users (name, age) VALUES (?, ?)', [name, age]); const userId = result.insertId; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return h.response(user).code(201); };
更新用户信息
接下来,我们需要定义一个 PUT 请求,用于更新用户信息。这个请求需要一个动态参数 id
,表示要更新的用户 ID,以及一个 JSON 格式的请求体,包含要更新的用户信息。我们可以使用类似下面的代码来定义路由和控制器:
// javascriptcn.com 代码示例 server.route({ method: 'PUT', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; const { name, age } = request.payload; await db.query('UPDATE users SET name = ?, age = ? WHERE id = ?', [name, age, userId]); const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return user; } }); const updateUserById = async (request, h) => { const userId = request.params.id; const { name, age } = request.payload; await db.query('UPDATE users SET name = ?, age = ? WHERE id = ?', [name, age, userId]); const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return user; };
删除用户信息
最后,我们需要定义一个 DELETE 请求,用于删除用户信息。这个请求需要一个动态参数 id
,表示要删除的用户 ID。我们可以使用类似下面的代码来定义路由和控制器:
// javascriptcn.com 代码示例 server.route({ method: 'DELETE', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; await db.query('DELETE FROM users WHERE id = ?', [userId]); return h.response().code(204); } }); const deleteUserById = async (request, h) => { const userId = request.params.id; await db.query('DELETE FROM users WHERE id = ?', [userId]); return h.response().code(204); };
完整的 API 示例
下面是一个完整的 RESTful API 示例,包含了上面定义的所有路由和控制器:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const Boom = require('@hapi/boom'); const db = require('./db'); const init = async () => { const server = Hapi.server({ port: 3000, host: 'localhost' }); server.route({ method: 'GET', path: '/users', handler: async (request, h) => { const users = await db.query('SELECT * FROM users'); return users; } }); server.route({ method: 'GET', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); if (!user) { throw Boom.notFound('User not found'); } return user; } }); server.route({ method: 'POST', path: '/users', handler: async (request, h) => { const { name, age } = request.payload; const result = await db.query('INSERT INTO users (name, age) VALUES (?, ?)', [name, age]); const userId = result.insertId; const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return h.response(user).code(201); } }); server.route({ method: 'PUT', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; const { name, age } = request.payload; await db.query('UPDATE users SET name = ?, age = ? WHERE id = ?', [name, age, userId]); const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]); return user; } }); server.route({ method: 'DELETE', path: '/users/{id}', handler: async (request, h) => { const userId = request.params.id; await db.query('DELETE FROM users WHERE id = ?', [userId]); return h.response().code(204); } }); await server.start(); console.log(`Server running on ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { console.log(err); process.exit(1); }); init();
总结
在本文中,我们介绍了如何使用 Hapi 框架来实现 RESTful API CRUD 操作。我们从基础的路由和控制器开始,逐步构建了一个完整的 API,并提供了一些示例代码和指导意义。希望这篇文章对你有所帮助,也欢迎你在评论中分享你的想法和经验。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6577efb2d2f5e1655d1babf3