API 设计:使用 Node.js 和 Express.js 的综合教程

API(应用程序编程接口)设计涉及创建一个高效而强大的接口,允许不同的软件应用程序相互交互。
说明
本教程将指导您使用 Node.js 和 Express.js 作为核心技术来规划、设计和构建 API。但是,这些原则可以应用于任何语言或框架。我们将创建一个简单的在线市场 API 作为工作示例。
让我们开始吧!
第 I 部分:规划 API
- 确定目的:设计 API 的第一步是确定它的用途。我们的 API 适用于在线市场,用户可以在其中查看待售商品并进行购买。
- 定义资源:接下来,确定 API 将处理的不同类型的数据。对于我们的市场,我们需要“物品”和“购买”的资源。
- 设计终结点:每个资源都应具有一组关联的终结点,这些终结点允许客户端与数据进行交互。使用 REST 原则,我们将为“项目”和“购买”创建终结点。
以下是 API 端点的粗略草图:
- GET /items:获取所有项目
- GET /items/:id:获取特定项目
- POST /items:添加新项目(仅限管理员)
- DELETE /items/:id:删除项目(仅限管理员)
- POST /purchases:进行新的购买
第 II 部分:构建 API
在本教程中,需要在计算机上安装 Node.js 和 npm。为您的项目创建一个新目录,在终端中导航到该目录,然后初始化一个新的 Node.js 项目:
mkdir marketplace-api && cd marketplace-api
npm init -y
接下来,安装 Express.js,一个流行的 Node.js Web 框架:
npm install express
2.1 设置服务器
让我们从设置一个基本的 Express 服务器开始。创建一个名为 :app.js
const express = require('express');
const app = express();app.listen(3000, () => console.log('Server listening on port 3000'));
您可以使用 启动服务器。服务器将在端口 3000 上启动。node app.js
2.2 创建终结点
让我们创建之前计划的终结点。首先,我们需要定义我们的数据。为简单起见,我们将使用内存中数组来存储数据:
let items = [];
let purchases = [];
我们还需要安装和使用 body-parser 中间件,以便 Express 能够理解 JSON body:
npm install body-parser
然后,在:app.js
const bodyParser = require('body-parser');
app.use(bodyParser.json());
现在,让我们创建终结点。以下是实现它们的方法:
查看所有项目:
app.get('/items', (req, res) => {res.json(items);
});
查看特定项目:
app.get('/items/:id', (req, res) => {const item = items.find(i => i.id === parseInt(req.params.id));if (!item) return res.status(404).send('Item not found');res.json(item);
});
添加项目(仅限管理员):
app.post('/items', (req, res) => {// This should be protectedconst newItem = {id: items.length + 1,name: req.body.name,price: req.body.price};items.push(newItem);res.status(201).json(newItem);
});
删除项目(仅限管理员):
app.delete('/items/:id', (req, res) => {// This should be protectedconst itemIndex = items.findIndex(i => i.id === parseInt(req.params.id));if (itemIndex === -1) return res.status(404).send('Item not found');const deletedItem = items.splice(itemIndex, 1);res.json(deletedItem);
});
进行购买:
app.post('/purchases', (req, res) => {// This should also check if the item exists and if the user has enough fundsconst newPurchase = {id: purchases.length + 1,userId: req.body.userId,itemId: req.body.itemId,};purchases.push(newPurchase);res.status(201).json(newPurchase);
});
第III 部分: 测试您的 API
您可以使用 Postman 或 curl 等工具测试您的 API。确保每个终结点都按预期运行并正确处理错误。始终使用不同类型的输入和场景进行测试,以确保 API 可靠。
第 IV 部分:记录 API
好的 API 文档可以包括概述、身份验证步骤、端点描述、错误代码和示例。您可以手动创建 API 文档,也可以使用工具自动生成 API 文档。
对于 Node.js,您可以使用 Swagger UI Express 等工具自动生成交互式文档。以下是有关如何设置它的快速示例:
- 安装必要的模块:
npm install swagger-ui-express yamljs
2. 创建一个新的 Swagger 规范文件:swagger.yaml
swagger: "2.0"
info:version: "1.0.0"title: "Marketplace API"
paths:/items:get:summary: "Get all items"responses:200:description: "A list of items"schema:$ref: '#/definitions/Item'
definitions:Item:type: "object"properties:id:type: "integer"name:type: "string"price:type: "number"
3. 在以下环境中导入并使用 Swagger UI:app.js
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const swaggerDocument = YAML.load('./swagger.yaml');app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
现在,您可以在 中查看 API 文档。localhost:3000/api-docs
第 V 部分:保护 API
您可以采取以下一些步骤来保护 API:
第 1 步:使用 HTTPS
Express.js 本身不支持 HTTPS,但在部署应用程序时,请确保使用支持 HTTPS 的提供程序,例如 AWS、Azure 或 Heroku。
第 2 步:身份验证
Express.js 没有内置的身份验证支持,但您可以使用 Passport.js 等中间件来处理此问题。
下面是如何设置基于令牌的身份验证的简化示例:
- 安装 Passport.js 和 JWT 策略:
npm install passport passport-jwt jsonwebtoken
2. 在您的 :app.js
const jwt = require('jsonwebtoken');
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;// Users should be stored in a database
let users = [{ id: '1', name: 'test', password: 'test', token: '' }];// JWT strategy
passport.use(new JwtStrategy({ secretOrKey: 'secret' }, (jwtPayload, done) => {const user = users.find(user => user.id === jwtPayload.id);if (user) {return done(null, user);} else {return done(null, false);}
}));// Login route
app.post('/login', (req, res) => {const user = users.find(user => user.name === req.body.username && user.password === req.body.password);if (user) {const token = jwt.sign({ id: user.id }, 'secret');user.token = token;res.json({ token });} else {res.sendStatus(401);}
});// Protected route
app.post('/items', passport.authenticate('jwt', { session: false }), (req, res) => {// Process request...
});
此设置要求客户端在标头中发送令牌。BearerAuthorization
第 3 步:授权
对于授权,请在处理请求之前检查用户的角色。例如:
app.post('/items', passport.authenticate('jwt', { session: false }), (req, res) => {if (req.user.role !== 'admin') return res.sendStatus(403);// Process request...
});
第 4 步:速率限制
Express.js 本身不支持速率限制,但有一些中间件包可以使用:express-rate-limit
npm install express-rate-limit
然后,在您的 :app.js
const rateLimit = require('express-rate-limit');const apiLimiter = rateLimit({windowMs: 15 * 60 * 1000, // 15 minutesmax: 100
});app.use('/api/', apiLimiter);
第 5 步:输入验证
始终验证 API 的输入。例如:
app.post('/items', (req, res) => {if (!req.body.name || !req.body.price) return res.status(400).send('Invalid input');// Process request...
});
第 6 步:错误处理
错误处理对于防止信息泄露非常重要。Express.js 会自动处理未捕获的异常并发送响应。自定义错误处理,如下所示:500 Internal Server Error
app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send('Something broke!');
});
请记住,安全是一个持续的过程。始终了解最新的安全最佳实践,并定期审核 API 是否存在漏洞。瓦利德·穆萨
相关文章:
API 设计:使用 Node.js 和 Express.js 的综合教程
API(应用程序编程接口)设计涉及创建一个高效而强大的接口,允许不同的软件应用程序相互交互。 说明 本教程将指导您使用 Node.js 和 Express.js 作为核心技术来规划、设计和构建 API。但是,这些原则可以应用于任何语言或框架。我们…...
vite和webpack的区别和练习
Vite和Webpack都是现代化的前端构建工具,但它们之间存在一些区别: 构建性能:Vite使用ES Modules提高了构建性能,可以在构建时只构建需要的部分,而Webpack则需要在构建时处理整个应用程序。 开发体验:Vite具…...
Python与设计模式--装饰器模式
6-Python与设计模式–装饰器模式 一、快餐点餐系统 又提到了那个快餐点餐系统,不过今天我们只以其中的一个类作为主角:饮料类。 首先,回忆下饮料类: class Beverage():name ""price 0.0type "BEVERAGE"…...
flutter之graphic图表自定义tooltip
renderer graphic中tooltip的TooltipGuide类提供了renderer方法,接收三个参数Size类型,Offset类型,Map<int, Tuple>类型。可查到的文档是真的少,所以只能在源码中扒拉例子,做符合需求的修改。 官方github示例 …...
逆向扒cocosjs安卓包教程-破解加密的js源码
本文只适用于cocosjs引擎打包的游戏apk,针对此类apk进行源码级别的逆向破解,可直接逐个破解工程内的源码部分,让游戏逻辑大白于你的面前,你可以针对js源码进行二次开发。按照我的教程破解过程中遇到什么问题,欢迎留言。 目录 准备apk包 查找加密key 解密jsc文件 方案1…...
Kafka(一)
一:简介 解决高吞吐量项目的需求 是一款为大数据而生的消息中间件,具有百亿级tps的吞吐量,在数据采集、传输、存储的过程中发挥着作用 二:为什么要使用消息队列 一个普通访问量的接口和一个大并发的接口,它们背后的…...
【Amazon】安装卸载AWS CLI操作流程(Windows 、Linux系统)
AWS 命令行界面(AWS CLI)是用于管理 AWS 产品的统一工具。只需要下载和配置一个工具,您就可以使用命令行控制多个 AWS 产品并利用脚本来自动执行这些服务。 AWS CLI v2 提供了多项新功能,包括改进的安装程序、新的配置选项&#…...
Django同时连接多种数据库
我的使用场景需要同时连接达梦数据库和MYSQL数据库,有的功能需要查询达梦,有的功能则需要查询MYSQL。 第一步:在 Django 的 settings.py 文件中,配置多个数据库连接。你可以在 DATABASES 字典中添加多个数据库配置。每个数据库配置…...
【链表之练习题】
文章目录 翻转链表找到链表的中间节点返回倒数第k个节点合并两个有序链表判断链表是否回文注意 翻转链表 //反转链表//实质上是把每一个节点头插法,原本第一个节点变成最后一个节点public ListNode reverseList(){//链表为空if (head null){return null;}//链表只有一个节点if…...
情感对话机器人的任务体系
人类在处理对话中的情感时,需要先根据对话场景中的蛛丝马迹判断出对方的情感,继而根据对话的主题等信息思考自身用什么情感进行回复,最后结合推理出的情感形成恰当的回复。受人类处理情感对话的启发,情感对话机器人需要完成以下几…...
【笔记 Pytorch 08】深度学习模板 (未完)
文章目录 一、声明二、工程结构三、文件内容main.pymodel.pydataset.pyutils.py 四、问题汇总 一、声明 非常感谢这些资料的作者: 【参考1】、【PyTorch速成教程 (by Sung Kim)】 二、工程结构 ├── main.py:实现训练 (train) 、验证(validation)和…...
【如何学习Python自动化测试】—— Cookie 处理
前提 网络通信是当今社会最为普及和繁荣的技术之一,其承载了人们生活中瞬息万变的信息传递和交流。而作为网络通信的核心要素,网络协议、socket、cookie和session则是网络通信的灵魂。 一、网络协议 网络协议是计算机和网络设备之间相互通信的规则和标准…...
IOS+Appium+Python自动化全实战教程
由于公司的产品坐落于不同的平台,如ios、mac、Android、windows、web。因此每次有新需求的时候,开发结束后,留给测试的时间也不多。此外,一些新的功能实现,偶尔会影响其他的模块功能正常的使用。 网上的ios自动化方面的…...
华硕灵耀XPro(UX7602ZM)原装Win11系统恢复安装教程方法
华硕灵耀XPro(UX7602ZM)原装Win11系统恢复安装教程方法: 第一步:需要自备华硕6个底包工厂安装包(EDN.KIT.OFS.SWP.HDI.TLK)或者自己备份的iso/esd/wim等镜像恢复 支持系列: 灵耀系列原装系统 无畏系列原装系统 枪…...
SpringBoot整合Redis,redis连接池和RedisTemplate序列化
SpringBoot整合Redis 1、SpringBoot整合redis1.1 pom.xml1.2 application.yml1.3 配置类RedisConfig,实现RedisTemplate序列化1.4 代码测试 2、SpringBoot整合redis几个疑问?2.1、Redis 连接池讲解2.2、RedisTemplate和StringRedisTemplate 3、RedisTemp…...
学习课题:逐步构建开发播放器【QT5 + FFmpeg6 + SDL2】
目录 一、播放器开发(一):播放器组成大致结构与代码流程设计 二、播放器开发(二):了解FFmpeg与SDL常用对象和函数 三、播放器开发(三):FFmpeg与SDL环境配置 四、播放器开发(四):多线程解复用与解码模块实现 五、播放器开发(五…...
Linux 6.7全面改进x86 CPU微码加载方式
导读最近,社区在清理 Linux 上的 Intel/AMD x86 CPU 微代码加载方面做了大量的工作,这些工作现已合并到 Linux 6.7 中。 由于在启动时加载 CPU 微代码对于减少不断出现的新 CPU 安全漏洞以及有时解决功能问题非常重要,Thomas Gleixner 最近开…...
【Python】Fastapi swagger-ui.css 、swagger-ui-bundle.js 无法加载,docs无法加载,redocs无法使用
使用fastapi的时候,swagger-ui.css 、swagger-ui-bundle.js、redoc.standalone.js 有时候无法加载(国内环境原因或者是局域网屏蔽),此时就需要自己用魔法下载好对应文件,然后替换到fastapi里面去。 fastapi里面依靠这…...
算法-中等-链表-两数相加
记录一下算法题的学习11 两数相加 题目:给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字…...
STC单片机选择外部晶振烧录程序无法切换回内部晶振导致单片机不能使用
STC单片机选择外部晶振烧录程序无法切换回内部晶振导致单片机不能使用 1.概述 在学习51单片机过程中,选择了STC的12C2052AD型号单片机作为入门芯片。前几个课题实验使用默认的内部晶振烧录程序,运行都没有问题。 选择一个LED亮度渐变的课题做实验&…...
EF Core 10 Vector Search扩展上线即崩?3个被官方文档隐藏的配置陷阱,92%团队已在凌晨紧急回滚
第一章:EF Core 10 Vector Search扩展的演进与核心定位EF Core 10 Vector Search 扩展并非孤立新增的功能模块,而是 Microsoft 在 .NET 生态中对向量数据库能力与 ORM 融合路径的一次关键性战略延伸。它标志着 EF Core 从传统关系型查询范式正式迈向支持…...
ExplorerPatcher深度解析:让Windows 11重获经典操作体验
ExplorerPatcher深度解析:让Windows 11重获经典操作体验 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher ExplorerPatcher是一款功能…...
全志D1s/F133 RISC-V处理器架构与应用解析
1. Allwinner D1s/F133 RISC-V处理器深度解析全志科技最新推出的D1s(又称F133)处理器,作为D1 RISC-V处理器的精简版本,在保持核心功能的同时通过集成64MB DDR2内存显著降低了成本。这款处理器主要面向智能摄像头和显示屏市场&…...
从医学图像到工业质检:UNet这个‘老将’为何在2024年依然能打?聊聊它的实战变形记
从医学图像到工业质检:UNet这个‘老将’为何在2024年依然能打?聊聊它的实战变形记 在深度学习模型日新月异的今天,Transformer和Diffusion模型占据了大量研究视线,但当我们把目光投向工业界实际应用场景——无论是PCB板上的微小缺…...
别再问0.1+0.2为什么不等于0.3了!用Go/Python代码带你手撕IEEE754浮点数精度陷阱
从0.10.2≠0.3出发:用代码解剖IEEE754浮点数的隐秘角落 当你在Python里输入0.1 0.2,期待得到0.3时,解释器却返回0.30000000000000004——这不是你的代码写错了,而是计算机存储数字的底层机制在"作怪"。这种现象在金融计…...
终极指南:如何让Mac鼠标滚轮像触控板一样丝滑滚动
终极指南:如何让Mac鼠标滚轮像触控板一样丝滑滚动 【免费下载链接】Mos 一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independently for y…...
别再调包了!手把手教你用Python封装一个万能分类模型评估函数(含10大模型对比)
从零构建Python分类模型评估工具箱:10大算法对比实战 每次完成分类模型训练后,你是否厌倦了反复调用sklearn.metrics计算各种指标?本文将带你从工程化角度,打造一个可复用的评估工具箱,并实战对比逻辑回归、XGBoost等1…...
从“零拷贝”到“写合并”:深入CUDA锁页内存的三种高级用法(附代码避坑)
从“零拷贝”到“写合并”:深入CUDA锁页内存的三种高级用法(附代码避坑) 在GPU加速计算的世界里,内存管理往往是性能优化的关键战场。当开发者已经掌握了CUDA基础内存操作后,锁页内存(Page-Locked Memory&a…...
别再只会用INNER JOIN了!Hive SQL里CROSS JOIN的这两个实战场景,帮你搞定复杂统计和ID续接
Hive SQL高阶实战:CROSS JOIN在复杂统计与ID续接中的妙用 笛卡尔积在SQL中常被视为性能杀手,但在特定场景下却能化身为解决问题的利器。今天我们就来探讨Hive中CROSS JOIN的两个高阶应用场景,这些技巧来自真实的数据仓库项目经验,…...
Page Assist架构解析:构建本地优先的浏览器AI助手技术方案
Page Assist架构解析:构建本地优先的浏览器AI助手技术方案 【免费下载链接】page-assist Use your locally running AI models to assist you in your web browsing 项目地址: https://gitcode.com/GitHub_Trending/pa/page-assist 在数据隐私日益重要的今天…...
