API Documentation - luckydeva03/desa_karangrejo GitHub Wiki

📖 API Documentation

Dokumentasi lengkap API untuk Website Desa Karangrejo.

🎯 Overview

API ini menyediakan akses programatik ke data dan fungsi Website Desa Karangrejo. API menggunakan RESTful principles dengan response format JSON.

🔑 Authentication

API Token Authentication

Authorization: Bearer your-api-token-here
Content-Type: application/json
Accept: application/json

Mendapatkan API Token

// Generate token di console atau admin panel
$user = User::find(1);
$token = $user->createToken('API Token')->plainTextToken;

🌐 Base URL

Production: https://your-domain.com/api/v1
Development: http://localhost:8000/api/v1

📝 Response Format

Success Response

{
    "success": true,
    "message": "Data retrieved successfully",
    "data": {
        // Response data here
    },
    "meta": {
        "current_page": 1,
        "total": 100,
        "per_page": 15
    }
}

Error Response

{
    "success": false,
    "message": "Validation failed",
    "errors": {
        "title": ["The title field is required."],
        "content": ["The content field is required."]
    }
}

📚 Available Endpoints

🏠 Public Data Endpoints

Get Village Information

GET /api/v1/village-info

Response:

{
    "success": true,
    "data": {
        "village_name": "Desa Karangrejo",
        "district": "Kecamatan XYZ",
        "regency": "Kabupaten ABC",
        "province": "Provinsi DEF",
        "postal_code": "12345",
        "website": "https://karangrejo.desa.id",
        "email": "[email protected]",
        "phone": "021-12345678"
    }
}

Get Latest Posts

GET /api/v1/posts

Parameters:

  • page (integer): Page number for pagination
  • per_page (integer): Items per page (max 50)
  • category (integer): Filter by category ID
  • search (string): Search in title and content

Example:

GET /api/v1/posts?page=1&per_page=10&category=1&search=pemilu

Response:

{
    "success": true,
    "data": [
        {
            "id": 1,
            "title": "Pengumuman Pemilu Desa 2024",
            "excerpt": "Pemilihan kepala desa akan dilaksanakan...",
            "content": "Full content here...",
            "featured_image": "https://domain.com/storage/posts/image.jpg",
            "category": {
                "id": 1,
                "name": "Pengumuman",
                "slug": "pengumuman"
            },
            "author": {
                "id": 1,
                "name": "Admin Desa"
            },
            "published_at": "2024-01-15T10:30:00Z",
            "reading_time": "3 menit",
            "views": 150
        }
    ],
    "meta": {
        "current_page": 1,
        "total": 25,
        "per_page": 10,
        "last_page": 3
    }
}

Get Single Post

GET /api/v1/posts/{id}

Response:

{
    "success": true,
    "data": {
        "id": 1,
        "title": "Pengumuman Pemilu Desa 2024",
        "content": "Full content with HTML...",
        "excerpt": "Short description...",
        "featured_image": "https://domain.com/storage/posts/image.jpg",
        "category": {
            "id": 1,
            "name": "Pengumuman",
            "slug": "pengumuman"
        },
        "author": {
            "id": 1,
            "name": "Admin Desa",
            "avatar": "https://domain.com/storage/avatars/admin.jpg"
        },
        "published_at": "2024-01-15T10:30:00Z",
        "updated_at": "2024-01-15T10:30:00Z",
        "reading_time": "3 menit",
        "views": 150,
        "related_posts": [
            {
                "id": 2,
                "title": "Related post title",
                "excerpt": "Related post excerpt...",
                "featured_image": "image.jpg"
            }
        ]
    }
}

Get Announcements

GET /api/v1/announcements

Parameters:

  • active (boolean): Only active announcements
  • limit (integer): Limit results (max 50)

Response:

{
    "success": true,
    "data": [
        {
            "id": 1,
            "title": "Pengumuman Penting",
            "content": "Isi pengumuman...",
            "type": "info", // info, warning, danger, success
            "is_active": true,
            "start_date": "2024-01-01",
            "end_date": "2024-01-31",
            "created_at": "2024-01-01T00:00:00Z"
        }
    ]
}

Get Gallery

GET /api/v1/gallery

Parameters:

  • category (integer): Filter by category ID
  • page (integer): Page number
  • per_page (integer): Items per page

Response:

{
    "success": true,
    "data": [
        {
            "id": 1,
            "title": "Kegiatan Gotong Royong",
            "description": "Kegiatan gotong royong membersihkan desa",
            "image": "https://domain.com/storage/gallery/image.jpg",
            "thumbnail": "https://domain.com/storage/gallery/thumbs/image.jpg",
            "category": {
                "id": 1,
                "name": "Kegiatan Desa"
            },
            "uploaded_at": "2024-01-15T10:30:00Z"
        }
    ],
    "meta": {
        "current_page": 1,
        "total": 50,
        "per_page": 12
    }
}

Get Village Data

GET /api/v1/village-data

Parameters:

  • type (string): Filter by data type (population, infrastructure, economy, etc.)

Response:

{
    "success": true,
    "data": [
        {
            "id": 1,
            "title": "Jumlah Penduduk",
            "value": "2,345",
            "unit": "jiwa",
            "type": "population",
            "icon": "users",
            "color": "blue",
            "description": "Total penduduk desa",
            "last_updated": "2024-01-01T00:00:00Z"
        },
        {
            "id": 2,
            "title": "Jumlah KK",
            "value": "650",
            "unit": "KK",
            "type": "population",
            "icon": "home",
            "color": "green"
        }
    ]
}

🔐 Protected Endpoints (Admin)

Create Post

POST /api/v1/admin/posts
Authorization: Bearer {token}

Request Body:

{
    "title": "Judul Post Baru",
    "content": "<p>Konten post dalam HTML...</p>",
    "excerpt": "Ringkasan post...",
    "category_id": 1,
    "status": "published", // draft, published
    "featured_image": "base64-encoded-image-data"
}

Response:

{
    "success": true,
    "message": "Post created successfully",
    "data": {
        "id": 15,
        "title": "Judul Post Baru",
        "slug": "judul-post-baru",
        "status": "published",
        "created_at": "2024-01-15T10:30:00Z"
    }
}

Update Post

PUT /api/v1/admin/posts/{id}
Authorization: Bearer {token}

Delete Post

DELETE /api/v1/admin/posts/{id}
Authorization: Bearer {token}

Upload Image

POST /api/v1/admin/upload
Authorization: Bearer {token}
Content-Type: multipart/form-data

Request:

POST /api/v1/admin/upload
Content-Type: multipart/form-data

--boundary
Content-Disposition: form-data; name="image"; filename="image.jpg"
Content-Type: image/jpeg

[binary data]
--boundary
Content-Disposition: form-data; name="folder"

posts
--boundary--

Response:

{
    "success": true,
    "message": "Image uploaded successfully",
    "data": {
        "url": "https://domain.com/storage/posts/image-123.jpg",
        "thumbnail": "https://domain.com/storage/posts/thumbs/image-123.jpg",
        "filename": "image-123.jpg",
        "size": 1024576
    }
}

📊 Analytics Endpoints

Get Website Statistics

GET /api/v1/admin/stats
Authorization: Bearer {token}

Response:

{
    "success": true,
    "data": {
        "total_posts": 45,
        "total_pages": 12,
        "total_gallery": 150,
        "total_visitors_today": 234,
        "total_visitors_month": 5670,
        "popular_posts": [
            {
                "id": 1,
                "title": "Popular post title",
                "views": 450
            }
        ],
        "recent_activities": [
            {
                "description": "New post created: Example Title",
                "user": "Admin",
                "created_at": "2024-01-15T10:30:00Z"
            }
        ]
    }
}

🚨 Error Codes

Code Description
200 Success
201 Created
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
422 Validation Error
429 Too Many Requests
500 Internal Server Error

🔄 Rate Limiting

  • Public endpoints: 60 requests per minute
  • Authenticated endpoints: 200 requests per minute
  • Upload endpoints: 10 requests per minute

📝 Request Headers

Content-Type: application/json
Accept: application/json
Authorization: Bearer {your-token}
X-Requested-With: XMLHttpRequest

🔍 Filtering & Sorting

Common Query Parameters

  • sort: Field to sort by (e.g., created_at, title, views)
  • order: Sort direction (asc or desc)
  • filter[field]: Filter by field value
  • search: Search in multiple fields

Example:

GET /api/v1/posts?sort=created_at&order=desc&filter[status]=published&search=desa

📄 Pagination

All paginated endpoints use consistent pagination:

{
    "data": [...],
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 5,
        "per_page": 15,
        "to": 15,
        "total": 75
    },
    "links": {
        "first": "https://domain.com/api/v1/posts?page=1",
        "last": "https://domain.com/api/v1/posts?page=5",
        "prev": null,
        "next": "https://domain.com/api/v1/posts?page=2"
    }
}

🔧 SDK & Libraries

JavaScript/Node.js

const axios = require('axios');

class DesaAPI {
    constructor(baseURL, token) {
        this.client = axios.create({
            baseURL: baseURL,
            headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
            }
        });
    }
    
    async getPosts(params = {}) {
        const response = await this.client.get('/posts', { params });
        return response.data;
    }
    
    async createPost(data) {
        const response = await this.client.post('/admin/posts', data);
        return response.data;
    }
}

// Usage
const api = new DesaAPI('https://karangrejo.desa.id/api/v1', 'your-token');
const posts = await api.getPosts({ page: 1, per_page: 10 });

PHP/Laravel

use Illuminate\Support\Facades\Http;

class DesaAPIClient
{
    protected $baseUrl;
    protected $token;
    
    public function __construct($baseUrl, $token)
    {
        $this->baseUrl = $baseUrl;
        $this->token = $token;
    }
    
    public function getPosts($params = [])
    {
        $response = Http::withToken($this->token)
            ->get($this->baseUrl . '/posts', $params);
            
        return $response->json();
    }
    
    public function createPost($data)
    {
        $response = Http::withToken($this->token)
            ->post($this->baseUrl . '/admin/posts', $data);
            
        return $response->json();
    }
}

🔄 Webhooks (Future Feature)

Webhook notifications untuk event penting:

  • post.created - Post baru dibuat
  • post.published - Post dipublikasikan
  • announcement.created - Pengumuman baru
  • contact.received - Pesan kontak diterima

API Documentation dibuat untuk kemudahan integrasi dengan sistem lain 📖