172 lines
3.9 KiB
Markdown
172 lines
3.9 KiB
Markdown
# Sea Battle — Main Server API
|
|
|
|
Базовый URL: `http://localhost:3000`
|
|
|
|
Все эндпоинты (кроме регистрации и входа) требуют заголовок:
|
|
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
---
|
|
|
|
## Аутентификация
|
|
|
|
### POST /api/register
|
|
|
|
Регистрация нового пользователя.
|
|
|
|
**Запрос** (`multipart/form-data` или `application/json`):
|
|
|
|
| Поле | Тип | Обязательное | Описание |
|
|
|------|-----|--------------|----------|
|
|
| `user[nickname]` | string | ✅ | 3–24 символа, уникальный |
|
|
| `user[password]` | string | ✅ | минимум 6 символов |
|
|
| `user[avatar]` | file | — | PNG, JPEG, GIF или WebP |
|
|
|
|
**Пример (curl):**
|
|
```bash
|
|
curl -X POST http://localhost:3000/api/register \
|
|
-F "user[nickname]=CaptainNemo" \
|
|
-F "user[password]=secret123" \
|
|
-F "user[avatar]=@avatar.png"
|
|
```
|
|
|
|
**Ответ `201 Created`:**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1,
|
|
"nickname": "CaptainNemo",
|
|
"avatar_url": "http://localhost:3000/rails/active_storage/blobs/...",
|
|
"created_at": "2025-09-20T18:00:00.000Z"
|
|
},
|
|
"token": "eyJhbGciOiJIUzI1NiJ9..."
|
|
}
|
|
```
|
|
|
|
**Ошибки:**
|
|
- `422 Unprocessable Entity` — невалидные данные:
|
|
```json
|
|
{ "errors": ["Nickname has already been taken"] }
|
|
```
|
|
```json
|
|
{ "errors": ["Nickname is too short (minimum is 3 characters)"] }
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/login
|
|
|
|
Вход по никнейму и паролю.
|
|
|
|
**Запрос** (`application/json`):
|
|
```json
|
|
{
|
|
"nickname": "CaptainNemo",
|
|
"password": "secret123"
|
|
}
|
|
```
|
|
|
|
**Ответ `200 OK`:**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1,
|
|
"nickname": "CaptainNemo",
|
|
"avatar_url": "http://localhost:3000/rails/active_storage/blobs/...",
|
|
"created_at": "2025-09-20T18:00:00.000Z"
|
|
},
|
|
"token": "eyJhbGciOiJIUzI1NiJ9..."
|
|
}
|
|
```
|
|
|
|
**Ошибки:**
|
|
- `401 Unauthorized`:
|
|
```json
|
|
{ "error": "Invalid nickname or password" }
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/logout
|
|
|
|
Выход. JWT является stateless — клиент должен удалить токен на своей стороне.
|
|
|
|
**Ответ `200 OK`:**
|
|
```json
|
|
{ "message": "Signed out successfully" }
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/me
|
|
|
|
Информация о текущем аутентифицированном пользователе.
|
|
|
|
**Ответ `200 OK`:**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1,
|
|
"nickname": "CaptainNemo",
|
|
"avatar_url": "http://localhost:3000/rails/active_storage/blobs/...",
|
|
"created_at": "2025-09-20T18:00:00.000Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Ошибки:**
|
|
- `401 Unauthorized`:
|
|
```json
|
|
{ "error": "Unauthorized" }
|
|
```
|
|
|
|
---
|
|
|
|
## Системные эндпоинты
|
|
|
|
### GET /up
|
|
|
|
Health check для мониторинга и load balancers.
|
|
|
|
**Ответ `200 OK`:**
|
|
```html
|
|
<!DOCTYPE html><html><body style="background-color: green"></body></html>
|
|
```
|
|
|
|
---
|
|
|
|
## Коды ошибок
|
|
|
|
| Код | Описание |
|
|
|-----|----------|
|
|
| `200` | Успех |
|
|
| `201` | Ресурс создан |
|
|
| `401` | Не авторизован (отсутствует/невалиден токен, неверный пароль) |
|
|
| `422` | Ошибка валидации |
|
|
|
|
## Валидации
|
|
|
|
| Поле | Правила |
|
|
|------|---------|
|
|
| `nickname` | 3–24 символа, уникальный (регистронезависимо) |
|
|
| `password` | минимум 6 символов |
|
|
| `avatar` | PNG, JPEG, GIF, WebP; опциональный |
|
|
|
|
## CORS
|
|
|
|
Настроен через `config/initializers/cors.rb`. По умолчанию разрешены все origins (`*`).
|
|
|
|
Для production задайте переменную окружения:
|
|
```bash
|
|
CORS_ORIGINS=https://your-frontend.com,https://www.your-frontend.com
|
|
```
|
|
|
|
## JWT
|
|
|
|
- Алгоритм: `HS256`
|
|
- Срок жизни: **7 дней**
|
|
- Секретный ключ: `Rails.application.secret_key_base`
|
|
- Payload: `{ "user_id": 1, "exp": 1234567890 }`
|