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 the 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/comuline/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 |