A robust, secure, and simple train ticket booking RESTful API built with Spring Boot.
- User registration and JWT authentication
- Manage train routes, stations, coaches, and seats
- Role-based access control (User/Admin)
- Swagger documentation (planned/future enhancement)
- Java 17
- Spring Boot 3
- Spring Security + JWT: For secure authentication and authorization.
- H2 Database (Development): In-memory database for development and testing.
- PostgreSQL (Production): Relational database for production environments.
- Spring Data JPA: For data persistence and ORM.
Instructions for setting up and running the project locally will be added here.
Base URL:
/api
| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /auth/register |
Register new account | ALL |
| POST | /auth/login |
Login & receive JWT | ALL |
| POST | /auth/forgot-password |
Request password reset token | ALL |
| POST | /auth/reset-password |
Reset password using token | ALL |
Endpoint : POST /api/auth/register
Request Body:
{
"email": "user@example.com",
"password": "password123",
"role": "USER"
}Response Body:
{
"status": true,
"messages": "User registration successful",
"errors": null,
"data": {
"id": "generated-uuid",
"email": "user@example.com",
"role": "USER"
},
"paging": null
}Endpoint : POST /api/auth/login
Request Body:
{
"email": "user@example.com",
"password": "password123"
}Response Body:
{
"status": true,
"messages": "Login successful",
"errors": null,
"data": {
"email": "user@example.com",
"token": "your-jwt-token",
"tokenType": "Bearer ",
"roles": [
"USER"
]
},
"paging": null
}Endpoint : POST /api/auth/forgot-password
Request Body:
{
"email": "user@example.com"
}Response Body:
{
"status": true,
"messages": "Password reset token sent to email",
"errors": null,
"data": {
"email": "user@example.com",
"token": "generated-reset-token"
},
"paging": null
}Endpoint : POST /api/auth/reset-password
Request Body:
{
"email": "user@example.com",
"token": "generated-reset-token",
"password": "new_password123"
}Response Body:
{
"status": true,
"messages": "Password reset successful",
"errors": null,
"data": null,
"paging": null
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /users |
Create new user (Admin) | ADMIN |
| GET | /users |
Get current user | USER/ADMIN |
| PATCH | /users |
Update current user | USER/ADMIN |
| GET | /users/list |
List all users with pagination | ADMIN |
Endpoint : POST /api/users
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"email": "newuser@example.com",
"password": "newpassword123",
"role": "USER"
}Response Body:
{
"status": true,
"messages": "User registration success",
"errors": null,
"data": {
"email": "newuser@example.com",
"fullName": null,
"phoneNumber": null,
"isVerified": false,
"isActive": true,
"role": [
"USER"
]
},
"paging": null
}Endpoint : GET /api/users
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "User fetching success",
"errors": null,
"data": {
"email": "currentuser@example.com",
"fullName": "Current User",
"phoneNumber": "+628123456789",
"isVerified": true,
"isActive": true,
"role": [
"USER"
]
},
"paging": null
}Endpoint : PATCH /api/users
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body:
{
"password": "updatedpassword",
"fullName": "Updated User Name",
"phoneNumber": "+628123456780",
"isVerified": true,
"isActive": true
}Response Body:
{
"status": true,
"messages": "User successfully updated",
"errors": null,
"data": {
"email": "currentuser@example.com",
"fullName": "Updated User Name",
"phoneNumber": "+628123456780",
"isVerified": true,
"isActive": true,
"role": [
"USER"
]
},
"paging": null
}Endpoint : GET /api/users/list
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All users successfully fetched",
"errors": null,
"data": [
{
"email": "admin@example.com",
"fullName": "Admin User",
"phoneNumber": "+628111111111",
"isVerified": true,
"isActive": true,
"role": [
"ADMIN"
]
},
{
"email": "user1@example.com",
"fullName": "User One",
"phoneNumber": "+628222222222",
"isVerified": true,
"isActive": true,
"role": [
"USER"
]
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /trains |
Create new train | USER/ADMIN |
| GET | /trains/{trainId} |
Get train by ID | USER/ADMIN |
| PATCH | /trains/{trainId} |
Update train by ID | USER/ADMIN |
| DELETE | /trains/{trainId} |
Delete train by ID | ADMIN |
| GET | /trains |
List all trains with pagination | USER/ADMIN |
| GET | /trains/search |
Search trains with pagination | USER/ADMIN |
| POST | /trains/{trainId}/coaches/{coachId} |
Assign coach to train | ADMIN |
| DELETE | /trains/{trainId}/coaches/{coachId} |
Remove coach from train | ADMIN |
Endpoint : POST /api/trains
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body:
{
"name": "Argo Wilis",
"trainType": "EXECUTIVE",
"operator": "KAI"
}Response Body:
{
"status": true,
"messages": "train registration success",
"errors": null,
"data": {
"id": 1,
"name": "Argo Wilis",
"trainType": "EXECUTIVE",
"operator": "KAI",
"isActive": true,
"coaches": []
},
"paging": null
}Endpoint : GET /api/trains/{trainId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Train fetching success",
"errors": null,
"data": {
"id": 1,
"name": "Argo Wilis",
"trainType": "EXECUTIVE",
"operator": "KAI",
"isActive": true,
"coaches": []
},
"paging": null
}Endpoint : PATCH /api/trains/{trainId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body:
{
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true
}Response Body:
{
"status": true,
"messages": "Train update success",
"errors": null,
"data": {
"id": 1,
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true,
"coaches": []
},
"paging": null
}Endpoint : DELETE /api/trains/{trainId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "train delete success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/trains
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All trains successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true,
"coaches": []
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/trains/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
name: (Optional) Train name to search fortrainType: (Optional) Train type to search foroperator: (Optional) Operator name to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All trains successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true,
"coaches": []
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : POST /api/trains/{trainId}/coaches/{coachId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Train assigning coach success",
"errors": null,
"data": {
"id": 1,
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true,
"coaches": [
"Executive A"
]
},
"paging": null
}Endpoint : DELETE /api/trains/{trainId}/coaches/{coachId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Train removing coach success",
"errors": null,
"data": {
"id": 1,
"name": "Argo Lawu",
"trainType": "BUSINESS",
"operator": "KAI",
"isActive": true,
"coaches": []
},
"paging": null
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /stations |
Create new station | ADMIN |
| GET | /stations/{stationId} |
Get station by ID | USER/ADMIN |
| PATCH | /stations/{stationId} |
Update station by ID | ADMIN |
| DELETE | /stations/{stationId} |
Delete station by ID | ADMIN |
| GET | /stations |
List all stations with pagination | USER/ADMIN |
| GET | /stations/search |
Search stations with pagination | USER/ADMIN |
Endpoint : POST /api/stations
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"code": "GMR",
"name": "Gambir",
"city": "Jakarta Pusat",
"province": "DKI Jakarta"
}Response Body:
{
"status": true,
"messages": "Station registration success",
"errors": null,
"data": {
"id": 1,
"code": "GMR",
"name": "Gambir",
"city": "Jakarta Pusat",
"province": "DKI Jakarta",
"isActive": true
},
"paging": null
}Endpoint : GET /api/stations/{stationId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Station fetching success",
"errors": null,
"data": {
"id": 1,
"code": "GMR",
"name": "Gambir",
"city": "Jakarta Pusat",
"province": "DKI Jakarta",
"isActive": true
},
"paging": null
}Endpoint : PATCH /api/stations/{stationId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"code": "GMI",
"name": "Gambir International",
"city": "Central Jakarta",
"province": "DKI Jakarta",
"isActive": true
}Response Body:
{
"status": true,
"messages": "Station update success",
"errors": null,
"data": {
"id": 1,
"code": "GMI",
"name": "Gambir International",
"city": "Central Jakarta",
"province": "DKI Jakarta",
"isActive": true
},
"paging": null
}Endpoint : DELETE /api/stations/{stationId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Station delete success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/stations
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All stations successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"code": "GMI",
"name": "Gambir International",
"city": "Central Jakarta",
"province": "DKI Jakarta",
"isActive": true
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/stations/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
code: (Optional) Station code to search forname: (Optional) Station name to search forcity: (Optional) City to search forprovince: (Optional) Province to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Station search executed successfully",
"errors": null,
"data": [
{
"id": 1,
"code": "GMI",
"name": "Gambir International",
"city": "Central Jakarta",
"province": "DKI Jakarta",
"isActive": true
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /routes |
Create new route | ADMIN |
| GET | /routes/origin/{originId}/destination/{destId} |
Get route by origin and destination ID | USER/ADMIN |
| PATCH | /routes/{routeId} |
Update route by ID | USER/ADMIN |
| DELETE | /routes/{routeId} |
Delete route by ID | ADMIN |
| GET | /routes |
List all routes with pagination | USER/ADMIN |
| GET | /routes/search |
Search routes with pagination | USER/ADMIN |
Endpoint : POST /api/routes
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"originId": 1,
"destId": 2,
"tripDistance": 150.5,
"tripDuration": 2.5
}Response Body:
{
"status": true,
"messages": "Route registration success",
"errors": null,
"data": {
"id": 1,
"originId": 1,
"origin": "Gambir",
"destId": 2,
"destination": "Bandung",
"tripDistance": 150.5,
"tripDuration": 2.5
},
"paging": null
}Endpoint : GET /api/routes/origin/{originId}/destination/{destId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Route fetching success",
"errors": null,
"data": {
"id": 1,
"originId": 1,
"origin": "Gambir",
"destId": 2,
"destination": "Bandung",
"tripDistance": 150.5,
"tripDuration": 2.5
},
"paging": null
}Endpoint : PATCH /api/routes/{routeId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body:
{
"originId": 1,
"destId": 3,
"tripDistance": 200.0,
"tripDuration": 3.0
}Response Body:
{
"status": true,
"messages": "Route update success",
"errors": null,
"data": {
"id": 1,
"originId": 1,
"origin": "Gambir",
"destId": 3,
"destination": "Yogyakarta",
"tripDistance": 200.0,
"tripDuration": 3.0
},
"paging": null
}Endpoint : DELETE /api/routes/{routeId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Route delete success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/routes
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All routes successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"originId": 1,
"origin": "Gambir",
"destId": 2,
"destination": "Bandung",
"tripDistance": 150.5,
"tripDuration": 2.5
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/routes/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
originCode: (Optional) Origin station code to search fordestCode: (Optional) Destination station code to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All routes successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"originId": 1,
"origin": "Gambir",
"destId": 2,
"destination": "Bandung",
"tripDistance": 150.5,
"tripDuration": 2.5
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /routeprices |
Create new route price | ADMIN |
| GET | /routeprices/{routePriceId} |
Get route price by ID | USER/ADMIN |
| PATCH | /routeprices/{routePriceId} |
Update route price by ID | ADMIN |
| DELETE | /routeprices/{routePriceId} |
Delete route price by ID | ADMIN |
| GET | /routeprices |
List all route prices with pagination | USER/ADMIN |
| GET | /routeprices/search |
Search route prices with pagination | USER/ADMIN |
Endpoint : POST /api/routeprices
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"coachTypeId": 1,
"routeId": 1,
"price": 150000.0
}Response Body:
{
"status": true,
"messages": "Route price registration success",
"errors": null,
"data": {
"id": 1,
"price": 150000.0,
"coachTypeId": 1,
"coachType": "Executive",
"routeId": 1,
"origin": "Gambir",
"destination": "Bandung"
},
"paging": null
}Endpoint : GET /api/routeprices/{routePriceId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Route price fetching success",
"errors": null,
"data": {
"id": 1,
"price": 150000.0,
"coachTypeId": 1,
"coachType": "Executive",
"routeId": 1,
"origin": "Gambir",
"destination": "Bandung"
},
"paging": null
}Endpoint : PATCH /api/routeprices/{routePriceId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"coachTypeId": 1,
"routeId": 1,
"price": 175000.0
}Response Body:
{
"status": true,
"messages": "Route price update success",
"errors": null,
"data": {
"id": 1,
"price": 175000.0,
"coachTypeId": 1,
"coachType": "Executive",
"routeId": 1,
"origin": "Gambir",
"destination": "Bandung"
},
"paging": null
}Endpoint : DELETE /api/routeprices/{routePriceId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Route price deletion success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/routeprices
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All route prices successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"price": 175000.0,
"coachTypeId": 1,
"coachType": "Executive",
"routeId": 1,
"origin": "Gambir",
"destination": "Bandung"
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/routeprices/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
originCode: (Optional) Origin station code to search fordestination: (Optional) Destination station name to search forcoachType: (Optional) Coach type to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All route prices successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"price": 175000.0,
"coachTypeId": 1,
"coachType": "Executive",
"routeId": 1,
"origin": "Gambir",
"destination": "Bandung"
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /coaches |
Create new coach | ADMIN |
| GET | /coaches/{coachId} |
Get coach by ID | ADMIN |
| PATCH | /coaches/{coachId} |
Update coach by ID | ADMIN |
| DELETE | /coaches/{coachId} |
Delete coach by ID | ADMIN |
| GET | /coaches |
List all coaches with pagination | ADMIN |
| GET | /coaches/search |
Search coaches with pagination | USER/ADMIN |
| POST | /coaches/{coachId}/seats/{seatId} |
Assign seat to coach | ADMIN |
| DELETE | /coaches/{coachId}/seats/{seatId} |
Remove seat from coach | ADMIN |
Endpoint : POST /api/coaches
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"coachName": "Executive A",
"coachNumber": 1,
"coachTypeId": 1
}Response Body:
{
"status": true,
"messages": "Coach registration success",
"errors": null,
"data": {
"id": 1,
"coachName": "Executive A",
"coachNumber": 1,
"coachTypeId": 1,
"coachTypeName": "Executive",
"seats": []
},
"paging": null
}Endpoint : GET /api/coaches/{coachId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Coach fetching success",
"errors": null,
"data": {
"id": 1,
"coachName": "Executive A",
"coachNumber": 1,
"coachTypeId": 1,
"coachTypeName": "Executive",
"seats": []
},
"paging": null
}Endpoint : PATCH /api/coaches/{coachId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2
}Response Body:
{
"status": true,
"messages": "Coach update success",
"errors": null,
"data": {
"id": 1,
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2,
"coachTypeName": "Business",
"seats": []
},
"paging": null
}Endpoint : DELETE /api/coaches/{coachId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Coach delete success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/coaches
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All coaches successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2,
"coachTypeName": "Business",
"seats": []
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/coaches/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
coachName: (Optional) Coach name to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All coaches successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2,
"coachTypeName": "Business",
"seats": []
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : POST /api/coaches/{coachId}/seats/{seatId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Coach assigning seat success",
"errors": null,
"data": {
"id": 1,
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2,
"coachTypeName": "Business",
"seats": [
"A1"
]
},
"paging": null
}Endpoint : DELETE /api/coaches/{coachId}/seats/{seatId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Coach removing seat success",
"errors": null,
"data": {
"id": 1,
"coachName": "Business B",
"coachNumber": 2,
"coachTypeId": 2,
"coachTypeName": "Business",
"seats": []
},
"paging": null
}| Method | Endpoint | Description | Allowed User |
|---|---|---|---|
| POST | /seats |
Create new seat | ADMIN |
| GET | /seats/{seatId} |
Get seat by ID | USER/ADMIN |
| PATCH | /seats/{seatId} |
Update seat by ID | ADMIN |
| DELETE | /seats/{seatId} |
Delete seat by ID | ADMIN |
| GET | /seats |
List all seats with pagination | USER/ADMIN |
| GET | /seats/search |
Search seats with pagination | USER/ADMIN |
Endpoint : POST /api/seats
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"seatNumber": "A1"
}Response Body:
{
"status": true,
"messages": "Seat registration success",
"errors": null,
"data": {
"id": 1,
"seatNumber": "A1"
},
"paging": null
}Endpoint : GET /api/seats/{seatId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Seat fetching success",
"errors": null,
"data": {
"id": 1,
"seatNumber": "A1"
},
"paging": null
}Endpoint : PATCH /api/seats/{seatId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body:
{
"seatNumber": "B2"
}Response Body:
{
"status": true,
"messages": "Seat update success",
"errors": null,
"data": {
"id": 1,
"seatNumber": "B2"
},
"paging": null
}Endpoint : DELETE /api/seats/{seatId}
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Allowed User : ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "Seat delete success",
"errors": null,
"data": null,
"paging": null
}Endpoint : GET /api/seats
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
page: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All seats successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"seatNumber": "B2"
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Endpoint : GET /api/seats/search
Request Header :
- Authorization : "Bearer " + Token (mandatory)
Request Parameters:
seatNumber: (Optional) Seat number to search forpage: Page number (default: 0)size: Number of items per page (default: 10)
Allowed User : USER/ADMIN
Request Body: None
Response Body:
{
"status": true,
"messages": "All seats successfully fetched",
"errors": null,
"data": [
{
"id": 1,
"seatNumber": "B2"
}
],
"paging": {
"currentPage": 0,
"totalPage": 1,
"size": 10
}
}Full API specification can be accessed through the Swagger UI (e.g., http://localhost:8080/swagger-ui.html) once the application is running.