宝塔面板快速搭建后端API与数据库教程

环境准备与安装

1. 安装宝塔面板

参考以下命令:

# CentOS安装命令
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh

# Ubuntu/Debian安装命令
wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh

2. 登录宝塔面板

安装完成后按照提示,通过浏览器访问链接,使用安装时显示的账号密码登录。

3. 安装必要软件

在宝塔面板中安装:

Nginx 1.20+

MySQL 5.7+

PHP 7.4+ (安装后安装Fileinfo和Redis扩展)

PM2管理器 (宝塔软件商店)

需要验证是否装上pm2,同时保证node环境安装(可使用node.js版本管理器)

pm2 --version
node -v
npm -v
# 使用淘宝镜像源
npm config set registry https://registry.npmmirror.com
# pm2安装
npm install -g pm2@latest

创建数据库

点击宝塔面板菜单”数据库” → “添加数据库”

填写信息示例:

数据库名:myapi_db

用户名:api_user

密码:StrongPassword123!

点击”提交”创建数据库

设置权限:选择”所有人”

点击管理 使用phpMyAdmin创建数据表

点击创建的数据库名,点击SQL,输入SQL语句运行查询

以下为示例SQL语句创建数据表和内容:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `users` (`name`, `email`) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com');

创建API项目

1. 创建项目目录

在/www/wwwroot下创建api目录,在目录中创建app.js文件

2. 安装依赖

cd /www/wwwroot/api
npm init -y
npm install express mysql body-parser cors

3.编写API代码 (app.js)

以下为示例参考:

const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();
app.use(cors());
app.use(bodyParser.json());

// 数据库配置 - 使用环境变量更安全
const db = mysql.createConnection({
  host: process.env.DB_HOST || 'localhost',
  user: process.env.DB_USER || 'api_user',
  password: process.env.DB_PASSWORD || 'StrongPassword123!',
  database: process.env.DB_NAME || 'myapi_db'
});

// 连接数据库
db.connect(err => {
  if (err) {
    console.error('数据库连接失败:', err.message);
    // 更友好的处理方式,而不是直接抛出错误
    process.exit(1); // 退出进程
  }
  console.log('MySQL数据库连接成功!');
});

// 添加根路由处理
app.get('/', (req, res) => {
  res.json({ 
    status: 'success',
    message: 'API is running!',
    endpoints: [
      '/api/users',
      '/api/users/:id'
    ]
  });
});

// 获取所有用户
app.get('/api/users', (req, res) => {
  const sql = 'SELECT * FROM users';
  db.query(sql, (err, results) => {
    if (err) {
      console.error('查询用户失败:', err);
      return res.status(500).json({ error: '数据库查询失败' });
    }
    res.json(results);
  });
});

// 获取单个用户 - 防止SQL注入
app.get('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  if (isNaN(userId)) {
    return res.status(400).json({ error: '无效的用户ID' });
  }
  
  const sql = 'SELECT * FROM users WHERE id = ?';
  db.query(sql, [userId], (err, results) => {
    if (err) {
      console.error('查询用户失败:', err);
      return res.status(500).json({ error: '数据库查询失败' });
    }
    if (results.length === 0) {
      return res.status(404).json({ error: '用户不存在' });
    }
    res.json(results[0]);
  });
});

// 创建用户 - 添加输入验证
app.post('/api/users', (req, res) => {
  const { name, email } = req.body;
  
  // 验证输入
  if (!name || !email) {
    return res.status(400).json({ error: '姓名和邮箱不能为空' });
  }
  
  const sql = 'INSERT INTO users (name, email) VALUES (?, ?)';
  db.query(sql, [name, email], (err, result) => {
    if (err) {
      console.error('创建用户失败:', err);
      return res.status(500).json({ error: '创建用户失败' });
    }
    res.status(201).json({ 
      id: result.insertId, 
      name, 
      email,
      message: '用户创建成功' 
    });
  });
});

// 更新用户 - 防止SQL注入
app.put('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  if (isNaN(userId)) {
    return res.status(400).json({ error: '无效的用户ID' });
  }
  
  const { name, email } = req.body;
  
  // 验证输入
  if (!name || !email) {
    return res.status(400).json({ error: '姓名和邮箱不能为空' });
  }
  
  const sql = 'UPDATE users SET name = ?, email = ? WHERE id = ?';
  db.query(sql, [name, email, userId], (err, result) => {
    if (err) {
      console.error('更新用户失败:', err);
      return res.status(500).json({ error: '更新用户失败' });
    }
    
    if (result.affectedRows === 0) {
      return res.status(404).json({ error: '用户不存在' });
    }
    
    res.json({ 
      id: userId, 
      name, 
      email,
      message: '用户更新成功' 
    });
  });
});

// 删除用户 - 防止SQL注入
app.delete('/api/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  if (isNaN(userId)) {
    return res.status(400).json({ error: '无效的用户ID' });
  }
  
  const sql = 'DELETE FROM users WHERE id = ?';
  db.query(sql, [userId], (err, result) => {
    if (err) {
      console.error('删除用户失败:', err);
      return res.status(500).json({ error: '删除用户失败' });
    }
    
    if (result.affectedRows === 0) {
      return res.status(404).json({ error: '用户不存在' });
    }
    
    res.json({ 
      id: userId,
      message: '用户删除成功' 
    });
  });
});

// 404 处理
app.use((req, res) => {
  res.status(404).json({ error: 'API端点不存在' });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error('服务器错误:', err.stack);
  res.status(500).json({ error: '服务器内部错误' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
  console.log(`API服务运行在 http://0.0.0.0:${PORT}`);
  console.log(`外部访问地址: http://${getPublicIp()}:${PORT}`);
});

// 获取公网IP的辅助函数
function getPublicIp() {
  // 在实际部署中,您可能需要从环境变量获取或使用外部服务
  return '192.168.1.1'; // 替换为您的实际公网IP
}

配置PM2管理API服务

打开宝塔面板的PM2管理器

添加新项目:

项目名称:api-server

运行目录:/www/wwwroot/api

启动文件:/www/wwwroot/api/app.js

点击”添加”启动服务

配置Nginx反向代理

点击宝塔面板菜单”网站” → “添加站点”

填写信息示例:

域名:api.yourdomain.com (或使用服务器IP)

根目录:/www/wwwroot/api

PHP版本:选择”纯静态”

点击”提交”创建站点

配置反向代理:

进入站点设置 → “反向代理” → “添加反向代理”

代理名称:api-proxy

目标URL:http://127.0.0.1:3000

发送域名:$host

其他保持默认 → 提交

配置防火墙和端口

在宝塔面板的“安全”界面,确保开放 3000 端口

测试 API

在浏览器中访问 http://your-server-ip:3000 检查是否能正常访问 API。

使用 Postman 或其他工具测试 /api/data 等具体 API 路径。

原创文章,作者:czhdawn,如若转载,请注明出处:https://www.czhdawn.cn/archives/4803

(0)
czhdawn的头像czhdawn
上一篇 2024年10月4日 16:57
下一篇 4天前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注