Files
sam-manage/app/Services/ApiExplorer/ApiExplorerService.php
hskwon 15a66a345e feat: API 사용 현황 및 폐기 후보 관리 기능 추가
- API 사용 통계 조회 및 미사용 API 식별 기능
- 폐기 후보 등록/상태변경/삭제 기능
- API Explorer에서 사용 현황 페이지 링크 추가
- 북마크 토글 버그 수정 (라우트-컨트롤러 메서드명 일치)
2025-12-18 20:26:17 +09:00

373 lines
10 KiB
PHP

<?php
namespace App\Services\ApiExplorer;
use App\Models\DevTools\ApiBookmark;
use App\Models\DevTools\ApiEnvironment;
use App\Models\DevTools\ApiHistory;
use App\Models\DevTools\ApiTemplate;
use Illuminate\Support\Collection;
/**
* API Explorer 비즈니스 로직 통합 서비스
*/
class ApiExplorerService
{
/*
|--------------------------------------------------------------------------
| Bookmark Operations
|--------------------------------------------------------------------------
*/
/**
* 즐겨찾기 목록 조회
*/
public function getBookmarks(int $userId): Collection
{
return ApiBookmark::where('user_id', $userId)
->ordered()
->get();
}
/**
* 즐겨찾기 추가
*/
public function addBookmark(int $userId, array $data): ApiBookmark
{
$maxOrder = ApiBookmark::where('user_id', $userId)->max('display_order') ?? 0;
return ApiBookmark::create([
'user_id' => $userId,
'endpoint' => $data['endpoint'],
'method' => strtoupper($data['method']),
'display_name' => $data['display_name'] ?? null,
'display_order' => $maxOrder + 1,
'color' => $data['color'] ?? null,
]);
}
/**
* 즐겨찾기 제거
*/
public function removeBookmark(int $bookmarkId): void
{
ApiBookmark::where('id', $bookmarkId)->delete();
}
/**
* 즐겨찾기 수정
*/
public function updateBookmark(int $bookmarkId, array $data): ?ApiBookmark
{
$bookmark = ApiBookmark::find($bookmarkId);
if (! $bookmark) {
return null;
}
if (isset($data['display_name'])) {
$bookmark->display_name = $data['display_name'];
}
$bookmark->save();
return $bookmark;
}
/**
* 즐겨찾기 순서 변경
*/
public function reorderBookmarks(int $userId, array $order): void
{
foreach ($order as $index => $id) {
ApiBookmark::where('id', $id)
->where('user_id', $userId)
->update(['display_order' => $index]);
}
}
/**
* 즐겨찾기 여부 확인
*/
public function isBookmarked(int $userId, string $endpoint, string $method): bool
{
return ApiBookmark::where('user_id', $userId)
->where('endpoint', $endpoint)
->where('method', strtoupper($method))
->exists();
}
/**
* 즐겨찾기 토글
*/
public function toggleBookmark(int $userId, array $data): array
{
$existing = ApiBookmark::where('user_id', $userId)
->where('endpoint', $data['endpoint'])
->where('method', strtoupper($data['method']))
->first();
if ($existing) {
$existing->delete();
return ['action' => 'removed', 'bookmark' => null];
}
$bookmark = $this->addBookmark($userId, $data);
return ['action' => 'added', 'bookmark' => $bookmark];
}
/*
|--------------------------------------------------------------------------
| Template Operations
|--------------------------------------------------------------------------
*/
/**
* 템플릿 목록 조회
*/
public function getTemplates(int $userId, ?string $endpoint = null, ?string $method = null): Collection
{
$query = ApiTemplate::where(function ($q) use ($userId) {
$q->where('user_id', $userId)
->orWhere('is_shared', true);
});
if ($endpoint) {
$query->where('endpoint', $endpoint);
}
if ($method) {
$query->where('method', strtoupper($method));
}
return $query->orderBy('name')->get();
}
/**
* 템플릿 저장
*/
public function saveTemplate(int $userId, array $data): ApiTemplate
{
return ApiTemplate::create([
'user_id' => $userId,
'endpoint' => $data['endpoint'],
'method' => strtoupper($data['method']),
'name' => $data['name'],
'description' => $data['description'] ?? null,
'headers' => $data['headers'] ?? null,
'path_params' => $data['path_params'] ?? null,
'query_params' => $data['query_params'] ?? null,
'body' => $data['body'] ?? null,
'is_shared' => $data['is_shared'] ?? false,
]);
}
/**
* 템플릿 수정
*/
public function updateTemplate(int $templateId, array $data): ApiTemplate
{
$template = ApiTemplate::findOrFail($templateId);
$template->update([
'name' => $data['name'] ?? $template->name,
'description' => $data['description'] ?? $template->description,
'headers' => $data['headers'] ?? $template->headers,
'path_params' => $data['path_params'] ?? $template->path_params,
'query_params' => $data['query_params'] ?? $template->query_params,
'body' => $data['body'] ?? $template->body,
'is_shared' => $data['is_shared'] ?? $template->is_shared,
]);
return $template->fresh();
}
/**
* 템플릿 삭제
*/
public function deleteTemplate(int $templateId): void
{
ApiTemplate::where('id', $templateId)->delete();
}
/*
|--------------------------------------------------------------------------
| History Operations
|--------------------------------------------------------------------------
*/
/**
* 요청 기록 저장
*/
public function logRequest(int $userId, array $data): ApiHistory
{
// 최대 개수 초과 시 오래된 것 삭제
$maxEntries = config('api-explorer.history.max_entries', 100);
$count = ApiHistory::where('user_id', $userId)->count();
if ($count >= $maxEntries) {
$deleteCount = $count - $maxEntries + 1;
ApiHistory::where('user_id', $userId)
->oldest('created_at')
->limit($deleteCount)
->delete();
}
return ApiHistory::create([
'user_id' => $userId,
'endpoint' => $data['endpoint'],
'method' => strtoupper($data['method']),
'request_headers' => $data['request_headers'] ?? null,
'request_body' => $data['request_body'] ?? null,
'response_status' => $data['response_status'],
'response_headers' => $data['response_headers'] ?? null,
'response_body' => $data['response_body'] ?? null,
'duration_ms' => $data['duration_ms'],
'environment' => $data['environment'],
]);
}
/**
* 히스토리 조회
*/
public function getHistory(int $userId, int $limit = 50): Collection
{
return ApiHistory::where('user_id', $userId)
->latest('created_at')
->limit($limit)
->get();
}
/**
* 히스토리 삭제
*/
public function clearHistory(int $userId): int
{
return ApiHistory::where('user_id', $userId)->delete();
}
/**
* 단일 히스토리 조회
*/
public function getHistoryItem(int $historyId): ?ApiHistory
{
return ApiHistory::find($historyId);
}
/*
|--------------------------------------------------------------------------
| Environment Operations
|--------------------------------------------------------------------------
*/
/**
* 환경 목록 조회
*/
public function getEnvironments(int $userId): Collection
{
return ApiEnvironment::where('user_id', $userId)
->orderBy('is_default', 'desc')
->orderBy('name')
->get();
}
/**
* 환경 저장
*/
public function saveEnvironment(int $userId, array $data): ApiEnvironment
{
// 기본 환경으로 설정 시 기존 기본 해제
if ($data['is_default'] ?? false) {
ApiEnvironment::where('user_id', $userId)
->update(['is_default' => false]);
}
return ApiEnvironment::create([
'user_id' => $userId,
'name' => $data['name'],
'base_url' => $data['base_url'],
'api_key' => $data['api_key'] ?? null,
'auth_token' => $data['auth_token'] ?? null,
'variables' => $data['variables'] ?? null,
'is_default' => $data['is_default'] ?? false,
]);
}
/**
* 환경 수정
*/
public function updateEnvironment(int $environmentId, array $data): ApiEnvironment
{
$environment = ApiEnvironment::findOrFail($environmentId);
// 기본 환경으로 설정 시 기존 기본 해제
if ($data['is_default'] ?? false) {
ApiEnvironment::where('user_id', $environment->user_id)
->where('id', '!=', $environmentId)
->update(['is_default' => false]);
}
$environment->update($data);
return $environment->fresh();
}
/**
* 환경 삭제
*/
public function deleteEnvironment(int $environmentId): void
{
ApiEnvironment::where('id', $environmentId)->delete();
}
/**
* 기본 환경 설정
*/
public function setDefaultEnvironment(int $userId, int $environmentId): void
{
// 기존 기본 해제
ApiEnvironment::where('user_id', $userId)
->update(['is_default' => false]);
// 새 기본 설정
ApiEnvironment::where('id', $environmentId)
->where('user_id', $userId)
->update(['is_default' => true]);
}
/**
* 기본 환경 조회
*/
public function getDefaultEnvironment(int $userId): ?ApiEnvironment
{
return ApiEnvironment::where('user_id', $userId)
->where('is_default', true)
->first();
}
/**
* 기본 환경 초기화 (설정된 환경이 없는 경우)
*/
public function initializeDefaultEnvironments(int $userId): void
{
$count = ApiEnvironment::where('user_id', $userId)->count();
if ($count > 0) {
return;
}
$defaults = config('api-explorer.default_environments', []);
foreach ($defaults as $index => $env) {
$this->saveEnvironment($userId, [
'name' => $env['name'],
'base_url' => $env['base_url'],
'api_key' => $env['api_key'] ?? null,
'is_default' => $index === 0,
]);
}
}
}