An API to get the schedule of KRL commuter line in Jakarta and Yogyakarta using Elsyia and Bun, deployed to Render. This API is primarily used on jadwal-krl.com web app (source code).
This API uses a daily cron job (at 00:00) to fetch the schedule of KRL commuter line in Jakarta and Yogyakarta from the official website of PT. KAI. The data is then processed and stored in a PostgreSQL database and cached in a Redis (for every once read request). All endpoints can be found in the docs.
- Elsyia API framework
- Bun runtime
- PostgresSQL (Neon)
- Redis (Upstash)
- Render deployment platform
- Drizzle ORM
- Clone the repository
git clone https://github.com/abielzulio/jadwal-krl-api.git
- Install the dependencies
bun install
- Run database locally
docker-compose up -d
- Copy the
.env.example
to.env
cp .env.example .env
- Run the database migration
bun db:generate && bun db:migrate
- Sync the data and populate it into your local database (once only as you needed)
# Please do this in order
# 1. Sync station data and wait until it's done
curl --request POST --url http://localhost:3001/v1/station/
# 2. Sync schedule data
curl --request POST --url http://localhost:3001/v1/schedule/
-
Create a new PostgreSQL database in Neon and copy the connection string value as
DATABASE_URL
in your.env
file -
Run the database migration
bun db:generate && bun db:migrate
- Sync the data and populate it into your remote database (once only as you needed)
# Please do this in order
# 1. Sync station data and wait until it's done
curl --request POST --url http://localhost:3001/v1/station/
# 2. Sync schedule data
curl --request POST --url http://localhost:3001/v1/schedule/
- Generate
SYNC_TOKEN
(This is used in production level only to prevent unauthorized access to yourPOST /v1/station
andPOST /v1/schedule
endpoint)
openssl rand -base64 32
# Copy the output value as a `SYNC_TOKEN`
-
Create a new Redis database in Upstash and copy the connection string value as
REDIS_URL
-
Create a
Web Service
in Render, copy theDATABASE_URL
,REDIS_URL
, andSYNC_TOKEN
as environment variables, and deploy the application. -
Set the cron job to fetch the schedule data using Cron-Job. Don't forget to set the
SYNC_TOKEN
as a header in your request. Add the?from_cron=true
query parameter to flag the request as a cron job request.
# Example
curl --request POST --url https://your-service-name.onrender.com/v1/station?from_cron=true -H "Authorization: Bearer ${SYNC_TOKEN}"
curl --request POST --url https://your-service-name.onrender.com/v1/schedule?from_cron=true -H "Authorization: Bearer ${SYNC_TOKEN}"
Station
Column Name | Data Type | Description |
---|---|---|
id | TEXT | Primary key (Station ID) |
name | TEXT | Station name |
daop | INTEGER | Station regional operation code |
fgEnable | BOOLEAN | - |
haveSchedule | BOOLEAN | Schedule availability status |
updatedAt | TEXT | Last updated date |
Schedule
Column Name | Data Type | Description |
---|---|---|
id | TEXT | Primary key (Station ID + Train ID) |
stationId | TEXT | Station ID |
trainId | TEXT | Train ID |
line | TEXT | Train commuter line |
route | TEXT | Train route |
color | TEXT | Commuter line color |
destination | TEXT | Train destination |
timeEstimated | TIME | Estimated time |
destinationTime | TIME | Destination time |
updatedAt | TEXT | Last updated date |
Sync
Column Name | Data Type | Description |
---|---|---|
id | TEXT | Primary key (Sync ID) |
n | BIGINT | n of sync |
type | ENUM | Sync type (manual, cron) |
status | ENUM | Sync status (PENDING, SUCCESS, FAILED) |
item | ENUM | Sync item (station, schedule) |
duration | BIGINT | Sync duration |
message | TEXT | Sync message (if status failed) |
startedAt | TEXT | Sync started date |
endedAt | TEXT | Sync ended date |
createdAt | TEXT | Sync created date |