制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Declare your data model, and eezo derives the rest from that one declaration: its table in Postgres, its HTML form, and CRUD routes that serve it.
case class Post(
id: Id[Post],
author: Id[User],
title: String,
body: String,
published: Boolean
) derives Table, Form, Resource
A case class automatically derives its Postgres table and a type-safe query API. As you change your data model, Eezo detects schema changes. When you're ready, you can commit them to a fingerprinted SQL migration.
A case class also gets 7 CRUD routes: index, new, create, show, edit, update and destroy,
served in a browser over rows in Postgres, with no need for a controller, repository or template
written by hand. Add Api to the derives clause and the same case class answers a program
with 5 JSON routes under /api, guarded by the same declaration as its pages.
You can add your own routes as a plain def in a file, and the file path becomes the HTTP route path.
You can also override a derived route on the same path.
Handlers are ordinary functions from a request to a response. Eezo runs on virtual threads, so blocking on the database or on an external API is cheap.
UIs are server-side rendered, with minimal functional Scala. A Component[State] has init, update and render, and can return HTML with Scala functions.
For the frontend, the browser gets a thin JS client which sends events to the server, and the server renders DOM diffs that get patched on the UI.
No need for
Deploying is done with eezo deploy on Fly.io.
synchronized.project/plugins.sbt:
addSbtPlugin("io.eezo" % "sbt-eezo" % "0.4.2")
build.sbt:
scalaVersion := "3.9.0"
enablePlugins(EezoPlugin)
libraryDependencies += "io.eezo" %% "eezo" % "0.4.2"
scalacOptions ++= Seq("-release", "25", "-deprecation", "-feature", "-unchecked", "-no-indent")
// The application forks, so it runs on the JDK sbt was told about rather than the one sbt runs on.
run / fork := true
Every artifact is published at the same version, under the io.eezo group:
| artifact | what it carries |
|---|---|
eezo | the umbrella and the default dependency |
eezo-http | the http layer: servers, requests and responses, routing, Form, Resource, Layout, HttpApp |
eezo-db | the database layer: the pool, the sql interpolator, transactions, Table, schema commands and migrations, DbApp |
eezo-auth | sessions, email and password sign in, CSRF, route guards and row ownership |
eezo-live | server-side rendered UI with the thin browser client: the diff and patch protocol, the client runtime, PubSub |
eezo-upickle | the JSON adapter for API routes: api.Serde for any model through upickle, not carried by the umbrella |
eezo-config | Config: the application's own configuration, read from application.conf, sections included |
eezo-core | what the others build on: Parser and Redacted, HTML tree and DSL, derivation, model keys |
sbt-eezo | the sbt plugin that generates the route table, for sbt 1 and sbt 2 |
An application has one or two layers, the http layer and the database layer. Use a layer by extending the appropriate trait in your app:
DbApp from eezo-dbHttpApp from eezo-httpEezoApp from eezo which mixes bothThe Layers doc explains more.
To start, you need two files. In src/main/scala/Main.scala:
import io.eezo.generated.Routes
import io.eezo.http.HttpApp
import io.eezo.http.RouteTable
object Main extends HttpApp {
override def routes: RouteTable = Routes.table()
}
Then in src/main/scala/app/Hello.scala:
package app
import io.eezo.core.html.*
import io.eezo.http.Request
import io.eezo.http.Response
object Hello {
def hello(request: Request): Response =
Response.Ok(
Html.doctype ++ html(
head(title("hello, eezo")),
body(h1("hello, eezo"), p("served at ", code(request.path)))
)
)
}
The Hello file is also the HTTP route. The plugin reads app/Hello.scala, mounts GET /hello calling
def hello, and writes the table to a generated io.eezo.generated.Routes, which Main contains as
its routes. A page is a value of Eezo's own HTML DSL. HttpApp brings main
with it:
sbt run # serves on http://localhost:8080
eezo dev # serves, restarting on every save, with the route listing
eezo routes # prints the table
Your first eezo application walks through this in about 20 minutes, and Routing says how a file name becomes a path.
Add the database layer by depending on either eezo or just eezo-db.
Make your case class derive Table, then add your tables (one line) to your schema:
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗