HttpServer with sqlite database (litefs). Deployable to fly.io.
You can use devbox:
devbox shell
If you use direnv, this happens automatically.
Otherwise you will need the packages mentioned in ./devbox.json
.
Compile scala code (includes code generation for database schema and smithy4s api):
sbt dev # compile - same as "webapp/fastLinkJS; httpServer/reStart"
sbt ~dev # or watch and compile
Run development server for frontend:
cd ./modules/webapp
yarn dev
Compile scala code:
sbt prod # compile - same as "webapp/fullLinkJS; httpServer/assembly"
sbt ~prod # or watch and compile
Run development server for frontend:
cd ./modules/webapp
yarn build
We use @keratin/authn-server
for handling authentication.
We use sqlite for this application. The deployed version (and the docker-compose version) use litefs to replicate sqlite to multiple instances.
We generate our scala database objects and schema definitions from an sql file.
Edit modules/db/schema.sql
to define the schema. This is the source of truth.
Then compile your code (db/compile
), this will regenerate scala files based on a scala template (modules/db/schema.scala.ssp
), and guide you.
We use the scala library magnum
for querying the database (see ./modules/db/src/main/scala/kicks/db/Db.scala
).
We run our migrations with flyway inside our scala application (see ./modules/db/src/main/resources/migrations/
and ./modules/db/src/main/scala/kicks/db/DbMigrations.scala
).
After editing modules/db/schema.sql
, you need to write a migration file. You can diff the schema against the current migrations and generate a migration file automatically: ./scripts/new-db-migration <title>
. You might need to edit the generated migration afterwards.
We generate our scala HTTP routes and json codecs from smithy files.
Edit ./modules/api/src/main/smithy/kicks.smithy
to define the API.
Then compile your code (api/compile
), this will regenerate scala files, and guide you.
An exception from the generation: smithy4s does not properly generate code for streaming.
That is why, we manually define our subscribe
streaming endpoint for ServerSentEvents - it is also not shown in the generated docs.
Our http server in scala is http4s
(see ./modules/httpServer/src/main/scala/kicks/http/Server.scala
and ./modules/httpServer/src/main/scala/kicks/http/ServerRoutes.scala
)
We use sloth
to have run RPC from frontend to backend via a scala trait. Check out ./modules/rpc/src/main/scala/kicks/rpc/Rpc.scala
.
The http server routes request to an implementation of that trait in ./modules/httpServer/src/main/scala/kicks/http/ServerRoutes.scala
.
The webapp client connects to the backend through method calls on that trait in ./modules/webapp/src/main/scala/kicks/webapp/RpcClient.scala
.
jdbc:sqlite:filename?foreign_keys=ON
in your jdbc connection strings. Or alternatively set #PRAGMA foreign_keys = ON
in each sqlite connection.