REST API demo for a search app to rent a property. Tech stack Bun, Hono, Drizzle, PlanetScale, Algolia, Clerk, Axiom, Upstash, RabbitMQ (CloudAMQP), Fly.io
Find more details in these blog articles:
- Real estate API for a search-to-rent application
- Clerk authentication, authorization, Upstash limiter, Axiom logging
- Test and deploy an OpenAPI with Github Actions
- Clone the repo and install dependencies
bun install
- Create a
.env.dev
file inside of the root of the project and fill in the variables after you setup PlanetScale (dev
branch), Google Maps Api, Pexels, Algolia, Clerk, CloudAMQP, Axiom, Upstash, Postman accounts.
BUN_ENV=development
DATABASE_NAME=<planetscale_database_name>
DATABASE_HOST=aws.connect.psdb.cloud
DATABASE_USERNAME=<planetscale_username>
DATABASE_PASSWORD=<planetscale_password>
DATABASE_URI=mysql://<planetscale_username>:<planetscale_password>@aws.connect.psdb.cloud/<planetscale_database_name>?ssl={"rejectUnauthorized": "true"}
GCLOUD_API_KEY=<gcloud_api_key>
PEXELS_API_KEY=<pexels_api_key>
ALGOLIA_APP_ID=<algolia_app_id>
ALGOLIA_ADMIN_API_KEY=<algolia_admin_api_key>
ALGOLIA_SEARCH_API_KEY=<algolia_search_api_key>
CLOUDAMQP_URL=<cloudamqp_url>
SERVER_TIMEZONE=Europe/Berlin
DATABASE_SEED_BLOCKED=false
POSTMAN_API_KEY=<postman_api_key>
CLERK_PUBLISHABLE_KEY=<clerk_publishable_key>
CLERK_SECRET_KEY=<clerk_secret_key>
CLERK_JWT_TEST=<clerk_jwt_test>
AXIOM_API_TOKEN=<axiom_api_token>
AXIOM_DATASET=<axiom_dataset>
UPSTASH_REDIS_REST_URL=<upstash_redis_rest_url>
UPSTASH_REDIS_REST_TOKEN=<upstash_redis_rest_token>
2.1 Create a .env.prod
file inside of the root of the project. This will be used to build the project
BUN_ENV=production
DATABASE_NAME=real-estate-api-demo
DATABASE_HOST=aws.connect.psdb.cloud
SERVER_TIMEZONE=Europe/Bucharest
DATABASE_SEED_BLOCKED=true
AXIOM_DATASET=real-estate-api-demo
2.2 To build the project use this command to prevent Bun reading .env.dev
at build time:
bun run move:up; bun run build; bun run move:down
- Clerk Setup. Create an organization. For your organization you have to create two custom roles:
Creator
andReader
and assign at least one verified user each.
See here details on how you can generate a JWT template on Clerk dashboard and based on that a long term JWT as CLERK_JWT_TEST
environment variable. Make sure your custom JWT template claims look like this:
{
"role": "{{org.role}}",
"email": "{{user.primary_email_address}}",
"fullName": "{{user.full_name}}"
}
- Install PlanetScale CLI
pscale
brew install planetscale/tap/pscale
- Install
mysql-client
brew install mysql-client
- Push schema to PlanetScale
bun run db:push
- Create database views (you need to be logged in to PlanetScale with
pscale
)
bun run db:create:views
- Seed the database. Before running the command bellow, you need to seed
community
(wikipedia scraping) andseedAddress
(Google Maps geocoder reverse) models first. See files heresrc/utils/db/seed/wiki
and heresrc/utils/db/seed/gmaps
.
bun run db:seed
- Block any accidental database seed from now on by setting this environment variable to
true
:
DATABASE_SEED_BLOCKED=true
- Create
all
table containing all data generated previously, to be used viasearchView
model for search testing purposes only. The search will be provided by Algolia to the frontend directly.
bun run db:create:all
- Seed Algolia
property-unit
index. This is going to be used directly by the frontend.
bun run algolia:seed
- Start the project in dev mode
bun run dev
- Access the API at:
http://localhost:3000
- Access the API Swagger documentation at:
http://localhost:3000/ui
- For client code generators access the JSON api specification at:
http://localhost:3000/doc
- Start Drizzle Studio
bun run db:studio
- Access Drizzle Studio at:
https://local.drizzle.studio/?port=3001
-
See entity relationship Draw.io diagram inside this folder
erd/entity-relationship-diagram.drawio
-
You can run normal tests
bun run test
- You can run Algolia workers tests
bun run test:workers
-
Install Postman and import
spec/real-estate-api-demo.postman_collection.json
. In Postman setbaseUrl
variable ashttp://localhost:3000
. Set a Postman environment variableclerk_jwt_test
and use it at the top authorization as aBearer Token
{{clerk_jwt_test}}
. All endpoints should have authorization header asInherit auth from parent
. -
Install Postman CLI with Homebrew
brew install --cask postman-cli
- You can run tests from Postman app or from CLI
bun run test:postman