{"id":29117753,"url":"https://github.com/ahmatfauzy/api-bookshelf","last_synced_at":"2026-04-10T20:47:47.545Z","repository":{"id":301178941,"uuid":"1008401169","full_name":"ahmatfauzy/api-bookshelf","owner":"ahmatfauzy","description":"REST API for book management built with Hapi.js | Dicoding Backend Course Final Project | Perfect Score ⭐⭐⭐⭐⭐ (B5)","archived":false,"fork":false,"pushed_at":"2025-06-25T14:31:59.000Z","size":78,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-10T20:46:53.996Z","etag":null,"topics":["api","backend","dicoding","dicoding-submission","eslint","hapijs","nodejs","rest-api","restful-api","server-side","submission"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahmatfauzy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T13:40:26.000Z","updated_at":"2025-06-26T04:51:29.000Z","dependencies_parsed_at":"2025-06-25T15:36:01.034Z","dependency_job_id":null,"html_url":"https://github.com/ahmatfauzy/api-bookshelf","commit_stats":null,"previous_names":["ahmatfauzy/api-bookshelf"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ahmatfauzy/api-bookshelf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmatfauzy%2Fapi-bookshelf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmatfauzy%2Fapi-bookshelf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmatfauzy%2Fapi-bookshelf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmatfauzy%2Fapi-bookshelf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahmatfauzy","download_url":"https://codeload.github.com/ahmatfauzy/api-bookshelf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmatfauzy%2Fapi-bookshelf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31658964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T17:19:37.612Z","status":"ssl_error","status_checked_at":"2026-04-10T17:19:13.364Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","backend","dicoding","dicoding-submission","eslint","hapijs","nodejs","rest-api","restful-api","server-side","submission"],"created_at":"2025-06-29T12:05:43.455Z","updated_at":"2026-04-10T20:47:47.540Z","avatar_url":"https://github.com/ahmatfauzy.png","language":"JavaScript","readme":"# Bookshelf API\n\nREST API untuk mengelola koleksi buku menggunakan Hapi.js Framework.\n\n## Features\n\n- ✅ Add new books\n- ✅ Get all books with filtering options\n- ✅ Get book details by ID\n- ✅ Update book information\n- ✅ Delete books\n- ✅ Query parameters for filtering (name, reading status, finished status)\n- ✅ Input validation and error handling\n- ✅ ESLint integration for code consistency\n\n## Instalasi\n\n```bash\nnpm install\nnpm start\n```\n\nServer akan berjalan di `http://localhost:9000`\n\n## API Endpoints\n\n### 1. Menambah Buku\n\n**POST** `/books`\n\n**Request Body:**\n```json\n{\n    \"name\": \"Belajar Node.js\",\n    \"year\": 2023,\n    \"author\": \"John Doe\",\n    \"summary\": \"Buku tentang pembelajaran Node.js dari dasar\",\n    \"publisher\": \"Dicoding Indonesia\",\n    \"pageCount\": 200,\n    \"readPage\": 50,\n    \"reading\": true\n}\n```\n\n**Response Success (201):**\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"Buku berhasil ditambahkan\",\n    \"data\": {\n        \"bookId\": \"1L7ZtDUFeGs7VlEt\"\n    }\n}\n```\n\n**Response Error - Nama kosong (400):**\n```json\n{\n\"status\": \"fail\",\n\"message\": \"Gagal menambahkan buku. Mohon isi nama buku\"\n}\n```\n\n**Response Error - readPage \u003e pageCount (400):**\n```json\n{\n\"status\": \"fail\",\n\"message\": \"Gagal menambahkan buku. readPage tidak boleh lebih besar dari pageCount\"\n}\n```\n\n---\n\n### 2. Menampilkan Semua Buku\n\n**GET** `/books`\n\n**Query Parameters (Opsional):**\n\n- `name` - Filter berdasarkan nama buku (case insensitive)\n- `reading` - Filter berdasarkan status membaca (0 atau 1)\n- `finished` - Filter berdasarkan status selesai (0 atau 1)\n\n**Contoh Request:**\n```\nGET /books\nGET /books?name=dicoding\nGET /books?reading=1\nGET /books?finished=0\nGET /books?name=node\u0026reading=1\n```\n\n**Response Success (200):**\n```json\n{\n    \"status\": \"success\",\n    \"data\": {\n        \"books\": [\n            {\n            \"id\": \"Qbax5Oy7L8WKf74l\",\n            \"name\": \"Belajar Node.js\",\n            \"publisher\": \"Dicoding Indonesia\"\n            },\n            {\n            \"id\": \"1L7ZtDUFeGs7VlEt\",\n            \"name\": \"Belajar React\",\n            \"publisher\": \"Dicoding Indonesia\"\n            }\n        ]\n    }\n}\n```\n\n**Response Kosong (200):**\n```json\n{\n    \"status\": \"success\",\n    \"data\": {\n        \"books\": []\n    }\n}\n```\n\n---\n\n### 3. Menampilkan Detail Buku\n\n**GET** `/books/{bookId}`\n\n**Contoh Request:**\n```\nGET /books/Qbax5Oy7L8WKf74l\n```\n\n**Response Success (200):**\n```json\n{\n    \"status\": \"success\",\n    \"data\": {\n        \"book\": {\n            \"id\": \"Qbax5Oy7L8WKf74l\",\n            \"name\": \"Belajar Node.js\",\n            \"year\": 2023,\n            \"author\": \"John Doe\",\n            \"summary\": \"Buku tentang pembelajaran Node.js dari dasar\",\n            \"publisher\": \"Dicoding Indonesia\",\n            \"pageCount\": 200,\n            \"readPage\": 50,\n            \"finished\": false,\n            \"reading\": true,\n            \"insertedAt\": \"2021-03-04T09:11:44.598Z\",\n            \"updatedAt\": \"2021-03-04T09:11:44.598Z\"\n        }\n    }\n}\n```\n\n**Response Error - Buku tidak ditemukan (404):**\n```json\n{\n    \"status\": \"fail\",\n    \"message\": \"Buku tidak ditemukan\"\n}\n```\n\n---\n\n### 4. Mengubah Data Buku\n\n**PUT** `/books/{bookId}`\n\n**Request Body:**\n```json\n{\n    \"name\": \"Belajar Node.js Lanjutan\",\n    \"year\": 2024,\n    \"author\": \"Jane Doe\",\n    \"summary\": \"Buku lanjutan tentang Node.js\",\n    \"publisher\": \"Dicoding Indonesia\",\n    \"pageCount\": 300,\n    \"readPage\": 100,\n    \"reading\": true\n}\n```\n\n**Response Success (200):**\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"Buku berhasil diperbarui\"\n}\n```\n\n**Response Error - Nama kosong (400):**\n```json\n{\n    \"status\": \"fail\",\n    \"message\": \"Gagal memperbarui buku. Mohon isi nama buku\"\n}\n```\n\n**Response Error - readPage \u003e pageCount (400):**\n```json\n{\n    \"status\": \"fail\",\n    \"message\": \"Gagal memperbarui buku. readPage tidak boleh lebih besar dari pageCount\"\n}\n```\n\n**Response Error - ID tidak ditemukan (404):**\n```json\n{\n    \"status\": \"fail\",\n    \"message\": \"Gagal memperbarui buku. Id tidak ditemukan\"\n}\n```\n\n---\n\n### 5. Menghapus Buku\n\n**DELETE** `/books/{bookId}`\n\n**Contoh Request:**\n```\nDELETE /books/Qbax5Oy7L8WKf74l\n```\n\n**Response Success (200):**\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"Buku berhasil dihapus\"\n}\n```\n\n**Response Error - ID tidak ditemukan (404):**\n```json\n{\n    \"status\": \"fail\",\n    \"message\": \"Buku gagal dihapus. Id tidak ditemukan\"\n}\n```\n\n## Catatan Penting\n\n- Properti `finished` dihitung otomatis berdasarkan `pageCount === readPage`\n- Properti `id`, `insertedAt`, dan `updatedAt` dikelola otomatis oleh server\n- Data disimpan dalam memori (akan hilang saat server restart)\n- Server berjalan di port 9000\n\n## Validation Rules\n\n- `name` is required\n- `readPage` cannot be greater than `pageCount`\n- `finished` is automatically calculated based on `pageCount === readPage`\n\n## Code Quality\n\nRun ESLint to check code quality:\n```bash\nnpm run lint\n```\n\nFix ESLint issues automatically:\n```bash\nnpm run lint:fix\n```\n\n## Port Configuration\n\nThe API runs on port 9000 by default. Make sure this port is available on your system.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmatfauzy%2Fapi-bookshelf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahmatfauzy%2Fapi-bookshelf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmatfauzy%2Fapi-bookshelf/lists"}