Simple tool to transpile Scala datamodel
This is a Scala-TS demonstration with a REST API managing user information, and a TypeScript SPA as frontend for this API.
The Scala API is developed using Akka HTTP, while the TypeScript frontend is based on Svelte.
This sample project will demonstrate how to share the data model between the Scala REST API and the TypeScript frontend in such situation.
Try it on Heroku
The application demonstrates several user management features.
The user can create a new account.
First, the user signs up using the Svelte form.
Then the frontend POST
s as JSON the TypeScript Account
.
e.g.
{
"userName": "xoo",
"password":"bar",
"usage":"Personal",
"favoriteFoods": [
"pizza",
{ "name": "ramen" }
],
"contactName": {
"firstName": "Lorem",
"lastName": "Ipsum",
"age": "23"
}
}
See TypeScript POST
The REST API receives the JSON data and decodes it as Scala Account
.
Note: Play JSON is used to read and write the Scala types from/to JSON requests/responses.
If it’s Ok, the Scala UserName
is sent back as JSON response.
Finally, frontend handles the response as TypeScript UserName
, and the Sign Up confirmation is displayed (or error if some).
Note: In this sample frontend, a type guard is used. In many case, validating the response must be done (e.g. io-ts, idonttrustlikethat, …); See demo with idonttrustlikethat.
The user can connect using his credentials, and then see his information on the profile screen.
First, the user type his name and password.
Then the frontend POST
s as JSON the TypeScript Credentials
.
{"userName":"foo","password":"bar"}
See TypeScript login
The REST API receives the JSON data and decodes it as Scala Credentials
.
If it’s Ok, a user token is sent back as JSON response.
Then the frontend redirects to the profile screen, which GET
s its information (according the token passed as HTTP authentication).
The REST API handles the user token, and finds the corresponding Scala Account
to send it back as JSON.
{
"userName": "foo",
"usage": "Personal",
"password": "bar",
"favoriteFoods": [ "pizza", "ramen" ]
}
Finally, the frontend receives the response as TypeScript Account
, and it’s displayed on the profile screen.
The demonstration models the user accounts and related information (username, credentials and token).
Scala | TypeScript |
---|---|
Account case class | Account interface |
UserName value class | string |
Credentials case class | Credentials interface |
UserToken value class | string |
The demonstration project is composed of multiple modules.
common: Common data model
Using Scala-TS, it declares the data model as Scala types, and from there the corresponding TypeScript types are generated.
lazy val common = (project in file("common")).
enablePlugins(TypeScriptGeneratorPlugin).
settings(
Seq(
name := "scala-ts-demo-common"
) ++ scalatsUnionWithLiteral)
http-api REST/HTTP API
Implements the use cases based on the data model
frontend TypeScript Svelte frontend
Using SBT:
sbt common/compile
to compile the Scala data model, and generate the corresponding TypeScript (to common/target/scala-ts/src_managed/
).sbt http-api/compile
to compile the REST API.Since #1 is ok, the TypeScript/Svelte frontend can be built (using the generated TypeScript).
cd frontend
export BACKEND_URL=http://http-api-base-url
yarn build
It can be deploy to Heroku using Docker build.
heroku.yml
Dockerfile
(copy frontend to src/main/resources/webroot
so it’s served as static resources).