// API 路径:/api/order/:id// 方法:GET// 描述:根据 ID 获取订单信息// datasource: business // 指定使用 business 数据源// SQL 语句SELECT * FROM orders WHERE id = #{pathParams.id}
3.3 脚本语言与内置函数
Magic API 支持 JavaScript 和 Groovy 两种脚本语言,并提供了丰富的内置函数库。下面是一些常用的内置函数示例:
让我们通过一个简单的用户管理系统来展示 Magic API 的实际应用。这个系统需要实现用户的增删改查功能。
4.1.1 用户列表 API
// API 路径:/api/users// 方法:GET// 描述:获取用户列表,支持分页和搜索// 前置脚本// 获取查询参数,设置默认值let page = queryParams.page || 1;
let size = queryParams.size || 10;
let keyword = queryParams.keyword || '';
// 计算偏移量let offset = (page - 1) * size;
// 构建查询条件let whereClause = '';
if(keyword){
whereClause = 'WHERE username LIKE #{keyword} OR email LIKE #{keyword}';
binding.keyword = '%'+ keyword +'%';
}
// SQL 语句SELECT * FROM user ${whereClause} LIMIT #{size} OFFSET #{offset};
SELECTCOUNT(*) as total FROM user ${whereClause};
// 后置脚本// 构造分页结果return {
"page": page,
"size": size,
"total": result[1][0].total,
"totalPages": Math.ceil(result[1][0].total / size),
"data": result[0]
};
4.1.2 创建用户 API
// API 路径:/api/users// 方法:POST// 描述:创建新用户// 前置脚本// 参数验证if(!body.username || body.username.trim()===''){
setStatusCode(400);
return {"error":"用户名不能为空","code":"USERNAME_REQUIRED"};
}
if(!body.email || body.email.trim()===''){
setStatusCode(400);
return {"error":"邮箱不能为空","code":"EMAIL_REQUIRED"};
}
// 检查用户名是否已存在let user = select.first('SELECT * FROM user WHERE username = #{body.username}');
if(user){
setStatusCode(400);
return {"error":"用户名已存在","code":"USERNAME_EXISTS"};
}
// 对密码进行加密
body.password = md5(body.password ||'123456');
// 设置默认密码
body.createdAt = date();
body.updatedAt = date();
// SQL 语句INSERTINTOuser(username, email, password, nickname, avatar, status, createdAt, updatedAt)
VALUES(#{body.username}, #{body.email}, #{body.password}, #{body.nickname}, #{body.avatar}, #{body.status}, #{body.createdAt}, #{body.updatedAt});
// 获取刚插入的用户 IDSELECTLAST_INSERT_ID() as id;
// 后置脚本// 获取新创建的用户信息let newUser = select.first('SELECT id, username, email, nickname, avatar, status, createdAt, updatedAt FROM user WHERE id = #{result[1][0].id}');
// 返回创建成功的用户信息setStatusCode(201);
return newUser;
4.1.3 更新用户 API
// API 路径:/api/users/:id// 方法:PUT// 描述:更新用户信息// 前置脚本let userId = pathParams.id;
// 检查用户是否存在let user = select.first('SELECT * FROM user WHERE id = #{userId}');
if(!user){
setStatusCode(404);
return {"error":"用户不存在","code":"USER_NOT_FOUND"};
}
// 如果更新密码,需要加密if(body.password){
body.password = md5(body.password);
}
// 更新时间
body.updatedAt = date();
// 构建更新字段let updateFields = [];
let updateBindings = {};
for(let key in body){
if(key !=='id'&& key !=='createdAt'){
// 排除 ID 和创建时间
updateFields.push(key +' = #{'+ key +'}');
updateBindings[key]= body[key];
}
}
// 合并绑定参数Object.assign(binding, updateBindings);
// SQL 语句UPDATE user SET ${updateFields.join(', ')} WHERE id = #{userId};
// 后置脚本// 获取更新后的用户信息let updatedUser = select.first('SELECT id, username, email, nickname, avatar, status, createdAt, updatedAt FROM user WHERE id = #{userId}');
return updatedUser;
4.1.4 删除用户 API
// API 路径:/api/users/:id// 方法:DELETE// 描述:删除用户// 前置脚本let userId = pathParams.id;
// 检查用户是否存在let user = select.first('SELECT * FROM user WHERE id = #{userId}');
if(!user){
setStatusCode(404);
return {"error":"用户不存在","code":"USER_NOT_FOUND"};
}
// SQL 语句DELETEFROM user WHERE id = #{userId};
// 后置脚本// 检查删除是否成功if(result >0){
return {"message":"删除成功"};
}else{
setStatusCode(500);
return {"error":"删除失败","code":"DELETE_FAILED"};
}
4.2 构建一个订单处理系统
接下来,让我们构建一个更复杂的订单处理系统,展示 Magic API 处理复杂业务逻辑的能力。
4.2.1 创建订单 API
// API 路径:/api/orders// 方法:POST// 描述:创建订单,包括检查库存、创建订单和扣减库存// 前置脚本beginTransaction();
try{
// 验证参数if(!body.userId ||!body.items ||!Array.isArray(body.items)|| body.items.length ===0){
setStatusCode(400);
return {"error":"参数错误","code":"INVALID_PARAMS"};
}
// 检查用户是否存在let user = select.first('SELECT * FROM user WHERE id = #{body.userId}');
if(!user){
setStatusCode(404);
return {"error":"用户不存在","code":"USER_NOT_FOUND"};
}
// 检查库存并计算总价let totalAmount = 0;
for(let item of body.items){
let product = select.first('SELECT * FROM product WHERE id = #{item.productId}');
if(!product){
setStatusCode(404);
return {"error":"商品不存在:"+ item.productId,"code":"PRODUCT_NOT_FOUND"};
}
let inventory = select.first('SELECT * FROM inventory WHERE productId = #{item.productId}');
if(!inventory || inventory.quantity < item.quantity){
setStatusCode(400);
return {"error":"库存不足:"+ product.name,"code":"INVENTORY_INSUFFICIENT"};
}
totalAmount += product.price * item.quantity;
}
// 生成订单号let orderNo ='ORD'+dateFormat(date(),'yyyyMMddHHmmss')+random(1000,9999);
// 创建订单let orderId =insert('INSERT INTO orders(userId, orderNo, totalAmount, status, createdAt, updatedAt) VALUES(#{body.userId}, #{orderNo}, #{totalAmount}, 0, #{date()}, #{date()})');
// 添加订单商品for(let item of body.items){
let product = select.first('SELECT * FROM product WHERE id = #{item.productId}');
insert('INSERT INTO order_item(orderId, productId, productName, price, quantity) VALUES(#{orderId}, #{item.productId}, #{product.name}, #{product.price}, #{item.quantity})');
// 扣减库存update('UPDATE inventory SET quantity = quantity - #{item.quantity} WHERE productId = #{item.productId}');
}
// 提交事务commitTransaction();
// 返回订单信息let order = select.first('SELECT * FROM orders WHERE id = #{orderId}');
let orderItems =select('SELECT * FROM order_item WHERE orderId = #{orderId}');
order.items = orderItems;
return order;
}catch(e){
// 发生异常,回滚事务rollbackTransaction();
log.error('创建订单失败:', e);
setStatusCode(500);
return {"error":"创建订单失败:"+ e.message,"code":"CREATE_ORDER_FAILED"};
}
4.2.2 订单支付 API
// API 路径:/api/orders/:id/pay// 方法:POST// 描述:订单支付// 前置脚本let orderId = pathParams.id;
let paymentMethod = body.paymentMethod ||'alipay'; // 默认使用支付宝beginTransaction();
try{
// 获取订单信息let order = select.first('SELECT * FROM orders WHERE id = #{orderId}');
if(!order){
setStatusCode(404);
return {"error":"订单不存在","code":"ORDER_NOT_FOUND"};
}
// 检查订单状态if(order.status !==0){ // 0 表示待支付setStatusCode(400);
return {"error":"订单状态不正确","code":"INVALID_ORDER_STATUS"};
}
// 模拟支付处理// 实际应用中,这里应该调用支付网关的 API
log.info('处理支付请求:',{orderId, amount: order.totalAmount, method: paymentMethod});
// 生成支付流水号let transactionNo ='TXN'+dateFormat(date(),'yyyyMMddHHmmss')+random(1000,9999);
// 创建支付记录insert('INSERT INTO payment(orderId, transactionNo, amount, paymentMethod, status, createdAt) VALUES(#{orderId}, #{transactionNo}, #{order.totalAmount}, #{paymentMethod}, 1, #{date()})');
// 更新订单状态update('UPDATE orders SET status = 1, updatedAt = #{date()} WHERE id = #{orderId}'); // 1 表示已支付// 提交事务commitTransaction();
// 发送支付成功事件
http.post('http://localhost:8080/api/events/payment-success',{
orderId: orderId,
orderNo: order.orderNo,
transactionNo: transactionNo,
amount: order.totalAmount
});
return {"message":"支付成功","orderId": orderId,"orderNo": order.orderNo,"transactionNo": transactionNo,"amount": order.totalAmount,"paymentMethod": paymentMethod };
}catch(e){
// 发生异常,回滚事务rollbackTransaction();
log.error('支付失败:', e);
setStatusCode(500);
return {"error":"支付失败:"+ e.message,"code":"PAYMENT_FAILED"};
}
4.3 构建一个统一的数据查询平台
Magic API 不仅可以用于构建业务系统,还可以用于构建统一的数据查询平台,为不同的用户提供定制化的数据查询服务。