536 lines
15 KiB
Bash
Executable File
536 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Script: scripts/restapi.sh
|
|
# Description: REST API Generator and Analyzer for Person Service
|
|
# Usage: ./scripts/restapi.sh [command] [options]
|
|
# Commands: generate, analyze, test, docs
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Project paths
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
HANDLERS_DIR="$PROJECT_ROOT/internal/infrastructure/transport/http/handlers"
|
|
GRPC_HANDLERS_DIR="$PROJECT_ROOT/internal/infrastructure/transport/grpc/handlers"
|
|
OUTPUT_DIR="$PROJECT_ROOT/docs/api"
|
|
SWAGGER_FILE="$OUTPUT_DIR/openapi.yaml"
|
|
POSTMAN_FILE="$PROJECT_ROOT/person.postman_collection.json"
|
|
|
|
# Default values
|
|
DEFAULT_HOST="localhost"
|
|
DEFAULT_PORT="8080"
|
|
DEFAULT_API_VERSION="v1"
|
|
|
|
# Helper functions
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Check if required files exist
|
|
check_requirements() {
|
|
log_info "Checking requirements..."
|
|
|
|
if [[ ! -f "$HANDLERS_DIR/person_handler.go" ]]; then
|
|
log_error "Person handler not found at $HANDLERS_DIR/person_handler.go"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$GRPC_HANDLERS_DIR/person_handler.go" ]]; then
|
|
log_error "gRPC person handler not found at $GRPC_HANDLERS_DIR/person_handler.go"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -d "$OUTPUT_DIR" ]]; then
|
|
mkdir -p "$OUTPUT_DIR"
|
|
fi
|
|
|
|
log_success "Requirements check passed"
|
|
}
|
|
|
|
# Extract endpoints from person_handler.go
|
|
extract_rest_endpoints() {
|
|
log_info "Extracting REST endpoints from person_handler.go..."
|
|
|
|
local handler_file="$HANDLERS_DIR/person_handler.go"
|
|
local endpoints_file="$OUTPUT_DIR/rest_endpoints.txt"
|
|
|
|
cat > "$endpoints_file" << 'EOF'
|
|
# REST API Endpoints - Person Service
|
|
# Generated on: $(date)
|
|
# Handler: internal/infrastructure/transport/http/handlers/person_handler.go
|
|
|
|
## Base Path: /api/v1/persons
|
|
|
|
### 1. Get List of Persons (Pagination)
|
|
- **Method**: GET
|
|
- **Path**: /persons
|
|
- **Query Parameters**:
|
|
- page (int, optional): Page number (default: 1)
|
|
- limit (int, optional): Items per page (default: 10)
|
|
- **Response**: Paginated list of persons
|
|
- **Handler**: PersonHandler.GetList()
|
|
|
|
### 2. Get Person Detail
|
|
- **Method**: GET
|
|
- **Path**: /persons/{id}
|
|
- **Path Parameters**:
|
|
- id (int64, required): Person ID
|
|
- **Response**: Single person details
|
|
- **Handler**: PersonHandler.GetDetail()
|
|
|
|
### 3. Create New Person
|
|
- **Method**: POST
|
|
- **Path**: /persons
|
|
- **Request Body**: CreatePersonRequest JSON
|
|
- **Response**: Created person details
|
|
- **Handler**: PersonHandler.Create()
|
|
|
|
### 4. Update Person
|
|
- **Method**: PUT
|
|
- **Path**: /persons/{id}
|
|
- **Path Parameters**:
|
|
- id (int64, required): Person ID
|
|
- **Request Body**: CreatePersonRequest JSON
|
|
- **Response**: Updated person details
|
|
- **Handler**: PersonHandler.Update()
|
|
|
|
EOF
|
|
|
|
log_success "REST endpoints extracted to $endpoints_file"
|
|
}
|
|
|
|
# Extract gRPC methods from person_handler.go
|
|
extract_grpc_endpoints() {
|
|
log_info "Extracting gRPC endpoints from person_handler.go..."
|
|
|
|
local grpc_handler_file="$GRPC_HANDLERS_DIR/person_handler.go"
|
|
local grpc_endpoints_file="$OUTPUT_DIR/grpc_endpoints.txt"
|
|
|
|
cat > "$grpc_endpoints_file" << 'EOF'
|
|
# gRPC API Endpoints - Person Service
|
|
# Generated on: $(date)
|
|
# Handler: internal/infrastructure/transport/grpc/handlers/person_handler.go
|
|
|
|
## Service: PersonService
|
|
|
|
### 1. GetPerson
|
|
- **Method**: GetPerson
|
|
- **Request**: GetPersonRequest { id: int64 }
|
|
- **Response**: GetPersonResponse { person: Person }
|
|
- **Handler**: PersonHandler.GetPerson()
|
|
|
|
### 2. ListPersons
|
|
- **Method**: ListPersons
|
|
- **Request**: ListPersonsRequest { page: int32, page_size: int32 }
|
|
- **Response**: ListPersonsResponse { persons: []Person, total: int64 }
|
|
- **Handler**: PersonHandler.ListPersons()
|
|
|
|
### 3. CreatePerson
|
|
- **Method**: CreatePerson
|
|
- **Request**: CreatePersonRequest { data: CreatePersonRequest }
|
|
- **Response**: GetPersonResponse { person: Person }
|
|
- **Handler**: PersonHandler.CreatePerson()
|
|
|
|
### 4. UpdatePerson
|
|
- **Method**: UpdatePerson
|
|
- **Request**: UpdatePersonRequest { id: int64, data: CreatePersonRequest }
|
|
- **Response**: GetPersonResponse { person: Person }
|
|
- **Handler**: PersonHandler.UpdatePerson()
|
|
|
|
### 5. DeletePerson
|
|
- **Method**: DeletePerson
|
|
- **Request**: DeletePersonRequest { id: int64 }
|
|
- **Response**: Empty {}
|
|
- **Handler**: PersonHandler.DeletePerson()
|
|
|
|
EOF
|
|
|
|
log_success "gRPC endpoints extracted to $grpc_endpoints_file"
|
|
}
|
|
|
|
# Generate Postman collection
|
|
generate_postman_collection() {
|
|
log_info "Generating Postman collection..."
|
|
|
|
cat > "$POSTMAN_FILE" << 'EOF'
|
|
{
|
|
"info": {
|
|
"name": "Person Service API",
|
|
"description": "REST API Collection for Person Service",
|
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
},
|
|
"item": [
|
|
{
|
|
"name": "Get Person List",
|
|
"request": {
|
|
"method": "GET",
|
|
"header": [],
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/persons?page=1&limit=10",
|
|
"host": ["{{base_url}}"],
|
|
"path": ["api", "v1", "persons"],
|
|
"query": [
|
|
{
|
|
"key": "page",
|
|
"value": "1",
|
|
"description": "Page number"
|
|
},
|
|
{
|
|
"key": "limit",
|
|
"value": "10",
|
|
"description": "Items per page"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "Get Person Detail",
|
|
"request": {
|
|
"method": "GET",
|
|
"header": [],
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/persons/1",
|
|
"host": ["{{base_url}}"],
|
|
"path": ["api", "v1", "persons", "1"]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "Create Person",
|
|
"request": {
|
|
"method": "POST",
|
|
"header": [
|
|
{
|
|
"key": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
],
|
|
"body": {
|
|
"mode": "raw",
|
|
"raw": "{\n \"name\": \"John Doe\",\n \"email\": \"[email protected]\",\n \"phone\": \"+1234567890\"\n}"
|
|
},
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/persons",
|
|
"host": ["{{base_url}}"],
|
|
"path": ["api", "v1", "persons"]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "Update Person",
|
|
"request": {
|
|
"method": "PUT",
|
|
"header": [
|
|
{
|
|
"key": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
],
|
|
"body": {
|
|
"mode": "raw",
|
|
"raw": "{\n \"name\": \"John Doe Updated\",\n \"email\": \"[email protected]\",\n \"phone\": \"+0987654321\"\n}"
|
|
},
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/persons/1",
|
|
"host": ["{{base_url}}"],
|
|
"path": ["api", "v1", "persons", "1"]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"variable": [
|
|
{
|
|
"key": "base_url",
|
|
"value": "http://localhost:8080",
|
|
"type": "string"
|
|
}
|
|
]
|
|
}
|
|
EOF
|
|
|
|
log_success "Postman collection generated at $POSTMAN_FILE"
|
|
}
|
|
|
|
# Generate Swagger documentation
|
|
generate_swagger_docs() {
|
|
log_info "Generating Swagger documentation..."
|
|
|
|
cat > "$SWAGGER_FILE" << 'EOF'
|
|
openapi: 3.0.0
|
|
info:
|
|
title: Person Service API
|
|
description: REST API for Person Management Service
|
|
version: 1.0.0
|
|
contact:
|
|
name: API Support
|
|
email: [email protected]
|
|
servers:
|
|
- url: http://localhost:8080/api/v1
|
|
description: Development server
|
|
paths:
|
|
/persons:
|
|
get:
|
|
summary: Get list of persons
|
|
description: Retrieve paginated list of persons
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
default: 1
|
|
- name: limit
|
|
in: query
|
|
description: Items per page
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
default: 10
|
|
responses:
|
|
'200':
|
|
description: Successful response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PaginatedPersonResponse'
|
|
post:
|
|
summary: Create new person
|
|
description: Create a new person record
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreatePersonRequest'
|
|
responses:
|
|
'201':
|
|
description: Person created successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PersonResponse'
|
|
/persons/{id}:
|
|
get:
|
|
summary: Get person detail
|
|
description: Retrieve detailed information about a specific person
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Person ID
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
responses:
|
|
'200':
|
|
description: Successful response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PersonResponse'
|
|
'404':
|
|
description: Person not found
|
|
put:
|
|
summary: Update person
|
|
description: Update an existing person record
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Person ID
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreatePersonRequest'
|
|
responses:
|
|
'200':
|
|
description: Person updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PersonResponse'
|
|
'404':
|
|
description: Person not found
|
|
components:
|
|
schemas:
|
|
CreatePersonRequest:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
phone:
|
|
type: string
|
|
required:
|
|
- name
|
|
- email
|
|
PersonResponse:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
name:
|
|
type: string
|
|
email:
|
|
type: string
|
|
phone:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
PaginatedPersonResponse:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PersonResponse'
|
|
meta:
|
|
type: object
|
|
properties:
|
|
page:
|
|
type: integer
|
|
limit:
|
|
type: integer
|
|
total:
|
|
type: integer
|
|
total_pages:
|
|
type: integer
|
|
EOF
|
|
|
|
log_success "Swagger documentation generated at $SWAGGER_FILE"
|
|
}
|
|
|
|
# Test API endpoints
|
|
test_api_endpoints() {
|
|
log_info "Testing API endpoints..."
|
|
|
|
local base_url="http://${DEFAULT_HOST}:${DEFAULT_PORT}"
|
|
local test_results="$OUTPUT_DIR/api_test_results.txt"
|
|
|
|
echo "API Test Results - $(date)" > "$test_results"
|
|
echo "================================" >> "$test_results"
|
|
echo "" >> "$test_results"
|
|
|
|
# Test health endpoint first
|
|
log_info "Testing health endpoint..."
|
|
if curl -s -o /dev/null -w "%{http_code}" "$base_url/health" | grep -q "200"; then
|
|
echo "✅ Health check: PASSED" >> "$test_results"
|
|
log_success "Health check passed"
|
|
else
|
|
echo "❌ Health check: FAILED" >> "$test_results"
|
|
log_error "Health check failed"
|
|
fi
|
|
|
|
# Test person list endpoint
|
|
log_info "Testing person list endpoint..."
|
|
local list_response=$(curl -s -w "\n%{http_code}" "$base_url/api/v1/persons?page=1&limit=5")
|
|
local list_http_code=$(echo "$list_response" | tail -n1)
|
|
|
|
if [[ "$list_http_code" == "200" ]] || [[ "$list_http_code" == "204" ]]; then
|
|
echo "✅ Person list endpoint: PASSED (HTTP $list_http_code)" >> "$test_results"
|
|
log_success "Person list endpoint working"
|
|
else
|
|
echo "❌ Person list endpoint: FAILED (HTTP $list_http_code)" >> "$test_results"
|
|
log_error "Person list endpoint failed"
|
|
fi
|
|
|
|
log_success "API test results saved to $test_results"
|
|
}
|
|
|
|
# Generate comprehensive API documentation
|
|
generate_api_docs() {
|
|
log_info "Generating comprehensive API documentation..."
|
|
|
|
local api_docs="$OUTPUT_DIR/API_DOCUMENTATION.md"
|
|
|
|
cat > "$api_docs" << 'EOF'
|
|
# Person Service API Documentation
|
|
|
|
## Overview
|
|
This document provides comprehensive documentation for the Person Service API, including REST and gRPC endpoints.
|
|
|
|
## Table of Contents
|
|
1. [REST API Endpoints](#rest-api-endpoints)
|
|
2. [gRPC API Endpoints](#grpc-api-endpoints)
|
|
3. [Request/Response Examples](#requestresponse-examples)
|
|
4. [Error Handling](#error-handling)
|
|
5. [Authentication](#authentication)
|
|
6. [Rate Limiting](#rate-limiting)
|
|
|
|
## REST API Endpoints
|
|
|
|
### Base URL
|
|
|
|
EOF
|
|
|
|
log_success "API documentation generated at $api_docs"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
local command="$1"
|
|
|
|
case "$command" in
|
|
"generate")
|
|
check_requirements
|
|
extract_rest_endpoints
|
|
extract_grpc_endpoints
|
|
generate_postman_collection
|
|
generate_swagger_docs
|
|
generate_api_docs
|
|
log_success "API generation completed"
|
|
;;
|
|
"analyze")
|
|
check_requirements
|
|
extract_rest_endpoints
|
|
extract_grpc_endpoints
|
|
log_success "API analysis completed"
|
|
;;
|
|
"test")
|
|
check_requirements
|
|
test_api_endpoints
|
|
log_success "API testing completed"
|
|
;;
|
|
"docs")
|
|
check_requirements
|
|
generate_api_docs
|
|
log_success "API documentation generated"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [generate|analyze|test|docs]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run main function
|
|
main "$@" |