Найти в Дзене

«API сервера: как связать веб‑сайт с игровым миром (примеры на PHP/Node.js)»

Компоненты системы: Поток данных: Создайте файл api.php: php <?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST");
$db = new PDO("mysql:host=localhost;dbname=game_db", "username", "password");
$endpoint = $_GET['endpoint'] ?? '';
switch ($endpoint) {
case 'player-stats':
getPlayerStats();
break;
case 'server-status':
getServerStatus();
break;
case 'send-command':
sendGameCommand();
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Endpoint not found']);
}
?> 1. Получение статистики игрока: php function getPlayerStats() {
global $db;
$playerName = $_GET['name'] ?? '';
if (empty($playerName)) {
http_response_code(400);
echo json_encode(['error' => 'Player name required']);
return;
}
$stmt = $db->prepare("SELECT * FROM players WHERE name = ?");
Оглавление

Архитектура решения

Компоненты системы:

  • игровой сервер (Minecraft, Unity, кастомный);
  • веб‑сервер с API (PHP/Node.js);
  • база данных (MySQL, PostgreSQL, MongoDB);
  • клиентская часть (веб‑сайт).

Поток данных:

  1. Игрок выполняет действие в игре.
  2. Игровой сервер отправляет данные на API.
  3. API обрабатывает и сохраняет данные в БД.
  4. Веб‑сайт запрашивает данные у API.
  5. API отдаёт данные в формате JSON.
  6. Веб‑сайт отображает информацию.

Пример на PHP

Шаг 1. Настройка API

Создайте файл api.php:

php

<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST");

$db = new PDO("mysql:host=localhost;dbname=game_db", "username", "password");

$endpoint = $_GET['endpoint'] ?? '';

switch ($endpoint) {
case 'player-stats':
getPlayerStats();
break;
case 'server-status':
getServerStatus();
break;
case 'send-command':
sendGameCommand();
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Endpoint not found']);
}
?>

Шаг 2. Реализация методов

1. Получение статистики игрока:

php

function getPlayerStats() {
global $db;
$playerName = $_GET['name'] ?? '';

if (empty($playerName)) {
http_response_code(400);
echo json_encode(['error' => 'Player name required']);
return;
}

$stmt = $db->prepare("SELECT * FROM players WHERE name = ?");
$stmt->execute([$playerName]);
$player = $stmt->fetch(PDO::FETCH_ASSOC);

if ($player) {
echo json_encode([
'name' => $player['name'],
'level' => $player['level'],
'experience' => $player['experience'],
'online' => $player['online']
]);
} else {
http_response_code(404);
echo json_encode(['error' => 'Player not found']);
}
}

2. Статус сервера:

php

function getServerStatus() {
// Здесь может быть проверка через RCON, WebSocket или файл состояния
echo json_encode([
'online_players' => 42,
'max_players' => 100,
'uptime' => '2d 5h',
'status' => 'online'
]);
}

3. Отправка команды в игру:

php

function sendGameCommand() {
$data = json_decode(file_get_contents('php://input'), true);
$command = $data['command'] ?? '';
$target = $data['target'] ?? '';

// Логика отправки команды на игровой сервер
// Например, через RCON для Minecraft

echo json_encode(['success' => true, 'message' => 'Command sent']);
}

Пример на Node.js

Шаг 1. Установка зависимостей

bash

npm init -y
npm install express mysql cors

Шаг 2. Создание сервера API

Файл server.js:

javascript

const express = require('express');
const mysql = require('mysql');
const cors = require('cors');

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

// Подключение к БД
const db = mysql.createConnection({
host: 'localhost',
user: 'username',
password: 'password',
database: 'game_db'
});

// Эндпоинты API
app.get('/api/player-stats', (req, res) => {
const playerName = req.query.name;
if (!playerName) {
return res.status(400).json({ error: 'Player name required' });
}

db.query('SELECT * FROM players WHERE name = ?', [playerName], (error, results) => {
if (error) return res.status(500).json({ error: 'Database error' });
if (results.length === 0) {
return res.status(404).json({ error: 'Player not found' });
}
res.json({
name: results[0].name,
level: results[0].level,
experience: results[0].experience,
online: results[0].online
});
});
});

app.get('/api/server-status', (req, res) => {
res.json({
online_players: 42,
max_players: 100,
uptime: '2d 5h',
status: 'online'
});
});

app.post('/api/send-command', (req, res) => {
const { command, target } = req.body;
// Отправка команды на игровой сервер
res.json({ success: true, message: 'Command sent' });
});

app.listen(3000, () => {
console.log('API server running on port 3000');
});

Интеграция с игровым сервером

Варианты подключения:

  1. RCON (для Minecraft):
    используйте библиотеки rcon для Node.js или php-rcon;
    отправляйте команды напрямую на игровой сервер.
  2. WebSockets:
    установите двустороннюю связь между игрой и API;
    подходит для реального времени.
  3. Файловый обмен:
    игровой сервер пишет данные в файл;
    API читает файл и отдаёт данные веб‑сайту.
  4. База данных:
    общий доступ к БД для игры и API;
    простой вариант для статических данных.
  5. HTTP‑запросы из игры:
    игра отправляет POST‑запросы на API;
    API обновляет БД и уведомляет веб‑сайт.

Веб‑сайт: запрос данных

JavaScript‑клиент для API

javascript

// Получение статистики игрока
async function getPlayerStats(name) {
try {
const response = await fetch(`/api/player-stats?name=${encodeURIComponent(name)}`);
const data = await response.json();
if (data.error) throw new Error(data.error);
displayPlayerStats(data);
} catch (error) {
console.error('Error:', error);
}
}

// Отображение данных на странице
function displayPlayerStats(player) {
document.getElementById('player-name').textContent = player.name;
document.getElementById('player-level').textContent = `Level: ${player.level}`;
document.getElementById('player-exp').textContent = `XP: ${player.experience}`;
}

// Обновление статуса сервера
function updateServerStatus() {
fetch('/api/server-status')
.then(response => response.json())
.then(data => {
document.getElementById('online-count').textContent = data.online_players;
document.getElementById('server-status').textContent = data.status;
});
}

Безопасность API

Обязательные меры:

  • Аутентификация: используйте API‑ключи или JWT.
  • Валидация входных данных: проверяйте все параметры запроса.
  • Ограничение частоты запросов (rate limiting): предотвратите DDoS.
  • HTTPS: шифруйте трафик.
  • CORS: настройте разрешённые домены.
  • Логирование: отслеживайте запросы и ошибки.

Пример проверки API‑ключа в PHP:

php

$validKeys = ['your-secret-key-123'];
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
if (!in_array($apiKey, $validKeys)) {
http_response_code(401);
echo json_encode(['error' => 'Invalid API key']);
exit;
}

Тестирование API

Инструменты:

  • Postman — для ручного тестирования эндпоинтов;
  • curl — для командной строки:bashcurl "http://localhost/api

Тестирование API

Инструменты для тестирования

1. Postman

Postman — графический инструмент для ручного тестирования API. Позволяет:

  • отправлять GET/POST/PUT/DELETE‑запросы;
  • настраивать заголовки (включая аутентификацию);
  • проверять ответы в формате JSON;
  • создавать коллекции тестов для автоматизации.

Пример использования:

  1. Создайте новый запрос.
  2. Выберите метод (GET, POST и т. д.).
  3. Введите URL: http://localhost:3000/api/player-stats?name=PlayerName.
  4. Добавьте заголовки, если нужно (например, X-API-Key: your-secret-key).
  5. Нажмите Send и проанализируйте ответ.

2. curl (командная строка)

Примеры команд:

  • GET‑запрос (статистика игрока):bashcurl "http://localhost:3000/api/player-stats?name=JohnDoe"
  • POST‑запрос (отправка команды в игру):bashcurl -X POST \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your-secret-key" \
    -d '{"command":"heal", "target":"JohnDoe"}' \
    "http://localhost:3000/api/send-command"
  • Проверка статуса сервера:bashcurl "http://localhost:3000/api/server-status"

3. Автоматизированное тестирование

  • Jest (для Node.js):javascriptconst request = require('supertest');
    const app = require('./server');

    describe('GET /api/player-stats', () => {
    it('should return player stats', async () => {
    const response = await request(app)
    .get('/api/player-stats')
    .query({ name: 'JohnDoe' });
    expect(response.statusCode).toBe(200);
    expect(response.body.name).toBe('JohnDoe');
    });
    });
  • PHPUnit (для PHP):phpclass ApiTest extends PHPUnit\Framework\TestCase {
    public function testPlayerStats() {
    $response = file_get_contents('http://localhost/api.php?endpoint=player-stats&name=JohnDoe');
    $data = json_decode($response, true);
    $this->assertEquals('JohnDoe', $data['name']);
    }
    }

Пошаговое тестирование эндпоинтов

Шаг 1. Проверка доступности API

bash

curl -I "http://localhost:3000"
# Ожидаемый ответ: HTTP/1.1 200 OK

Шаг 2. Тестирование GET‑эндпоинтов

  • /api/player-stats?name=PlayerName:
    успешный случай: статус 200, JSON с данными игрока;
    ошибка 400: отсутствует параметр name;
    ошибка 404: игрок не найден.
  • /api/server-status:
    статус 200, JSON с текущим статусом сервера.

Шаг 3. Тестирование POST‑эндпоинтов

bash

curl -X POST \
-H "Content-Type: application/json" \
-d '{"command":"teleport", "target":"PlayerName"}' \
"http://localhost:3000/api/send-command"

  • успешный случай: статус 200, { "success": true };
  • ошибка 500: сервер не может выполнить команду.

Шаг 4. Проверка ошибок

  • отправьте запрос с неверным методом (например, POST вместо GET);
  • проверьте обработку отсутствующих параметров;
  • протестируйте неверные данные (например, пустой name).

Шаг 5. Нагрузочное тестирование
Используйте ab (Apache Benchmark):

bash

ab -n 100 -c 10 "http://localhost:3000/api/server-status"

Это отправит 100 запросов с 10 параллельными соединениями.

Мониторинг и логирование

Логирование запросов в Node.js:

javascript

app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`${req.method} ${req.path} ${res.statusCode} ${duration}ms`);
});
next();
});

Логирование в PHP:

php

$logEntry = date('Y-m-d H:i:s') . " " . $_SERVER['REMOTE_ADDR'] . " " .
$_SERVER['REQUEST_METHOD'] . " " . $_SERVER['REQUEST_URI'] . "\n";
file_put_contents('api_access.log', $logEntry, FILE_APPEND);

Мониторинг в реальном времени:

  • используйте tail -f api_access.log для отслеживания запросов;
  • настройте оповещения при ошибках 5xx.

Устранение распространённых проблем

1. «404 Not Found»

  • проверьте URL и маршрут в коде;
  • убедитесь, что сервер запущен.

2. «401 Unauthorized»

  • добавьте заголовок X-API-Key с правильным ключом;
  • проверьте валидность API‑ключа.

3. «500 Internal Server Error»

  • посмотрите логи сервера;
  • проверьте подключение к БД;
  • убедитесь, что все зависимости установлены.

4. «No ‘Access-Control-Allow-Origin’»

  • включите CORS в настройках API;
  • для PHP добавьте:phpheader("Access-Control-Allow-Origin: *");
  • для Node.js используйте пакет cors.

5. «Empty response»

  • проверьте синтаксис JSON в ответе;
  • убедитесь, что заголовки Content-Type установлены правильно.

6. «Connection refused»

  • проверьте порт сервера (3000 по умолчанию);
  • убедитесь, что брандмауэр не блокирует соединение.

Чек‑лист тестирования API

  1. Доступность: сервер отвечает на базовые запросы.
  2. GET‑эндпоинты:
    корректные данные возвращаются при правильных параметрах;
    ошибки 400/404 при неверных параметрах.
  3. POST‑эндпоинты:
    команды выполняются и возвращают статус 200;
    обработка ошибок (500) при сбое.
  4. Безопасность:
    аутентификация обязательна для защищённых эндпоинтов;
    неверные ключи блокируются.
  5. Производительность:
    сервер выдерживает нагрузку (тест ab);
    время ответа в пределах нормы (<500 мс).
  6. Логирование:
    все запросы записываются в лог;
    ошибки детализированы.
  7. CORS:
    запросы с веб‑сайта разрешены;
    кросс‑доменные запросы работают.

Рекомендации по улучшению

  • Документация API: создайте Swagger/OpenAPI‑спецификацию для описания эндпоинтов.
  • Кэширование: используйте Redis для кэширования частых запросов (например, статуса сервера).
  • Rate limiting: ограничьте количество запросов с IP (например, 100/мин) для защиты от DDoS.
  • Версионирование API: добавьте версию в URL (/api/v1/...) для обратной совместимости.
  • Health check: создайте эндпоинт /health для мониторинга состояния API.

Теперь у вас есть полный набор инструментов для тестирования и отладки API, связывающего веб‑сайт с игровым миром. Если хотите, могу помочь адаптировать примеры под ваш проект или разобрать конкретный сценарий!