Quick Start
This documentation needs to be written. You can help us by contributing to the documentation. |
Installation
This library is currently available for Scala binary version 3.3.1.
To use the latest version, include the following in your build.sbt
:
libraryDependencies ++= Seq(
"com.rlemaitre" %% "pillars-core" % "0.4.4"
)
You can also add optional modules to your dependencies:
libraryDependencies ++= Seq(
"com.rlemaitre" %% "pillars-db" % "0.4.4",
"com.rlemaitre" %% "pillars-db-migration" % "0.4.4",
"com.rlemaitre" %% "pillars-flags" % "0.4.4",
"com.rlemaitre" %% "pillars-http-client" % "0.4.4"
)
Usage
You can find an example project in the modules/example
directory.
First, you need to create a configuration file.
You can find an example in the modules/example/src/main/resources/application.conf
file.
Then, you can create your entry point by extending the pillars.IOApp
trait:
object app extends pillars.IOApp(DB, DBMigration, FeatureFlags, HttpClient): // (1)
def infos: AppInfo = BuildInfo.toAppInfo // (2)
def run: Run[IO, IO[Unit]] = // (3)
for
_ <- logger.info(s"📚 Welcome to ${config.name}!")
_ <- dbMigration.migrate("classpath:db-migrations") // (4)
_ <- flag"feature-1".whenEnabled:
sessions.use: session =>
for
date <- session.unique(sql"select now()".query(timestamptz))
_ <- logger.info(s"The current date is $date.")
yield ()
_ <- http.get("https://swapi.dev/api/people/1"): response =>
for
_ <- logger.info(s"Response: ${response.status}")
size <- response.body.compile.count
_ <- logger.info(s"Body: $size bytes")
yield ()
_ <- server.start(homeController, userController) // (5)
yield ()
end for
end run
end app
1 | The EntryPoint trait is a simple trait that provides a main method and initialize the Pillars instance. |
2 | infos defines some metadata about your application.
It is used by the admin server to display information about your application.
See Application Metadata for more information. |
3 | The run is the entry point of your application.
Thanks to the Run[F[_], T] context function, you have access to a Pillars[F] instance that contains all your modules. |
4 | Each module is accessible through the Pillars instance or through a top-level function in the module’s package.
The dbMigration.migrate function is a top-level function that is provided by the db-migration module. |
5 | The API server must be started with the server.start function with the controllers you want to expose. |
Then, you can run your application. For example, you can run it with sbt
:
sbt "example/run"
The log should display something like:
2024.01.21 22:36:19:0000 [io-comp...] [INFO ] pillars.Pillars.apply:52 - Loading modules...
2024.01.21 22:36:19:0001 [io-comp...] [INFO ] pillars.Pillars.loadModules:87 - Found 2 module loaders: db, feature-flags
2024.01.21 22:36:19:0002 [io-comp...] [INFO ] pillars.db.db.load:57 - Loading DB module
2024.01.21 22:36:19:0003 [io-comp...] [INFO ] pillars.db.db.load:68 - DB module loaded
2024.01.21 22:36:19:0004 [io-comp...] [INFO ] pillars.flags.FlagManager.load:54 - Loading Feature flags module
2024.01.21 22:36:19:0005 [io-comp...] [INFO ] pillars.flags.FlagManager.load:57 - Feature flags module loaded
2024.01.21 22:36:19:0000 [io-comp...] [INFO ] pillars.AdminServer.start:22 - Starting admin server on 0.0.0.0:19876
2024.01.21 22:36:19:0006 [io-comp...] [INFO ] example.app.run:24 - 📚 Welcome to Bookstore!
2024.01.21 22:36:19:0000 [io-comp...] [INFO ] example.app.run:29 - The current date is 2024-01-21T22:36:19.695572+01:00.
2024.01.21 22:36:19:0000 [io-comp...] [INFO ] pillars.ApiServer.init:21 - Starting API server on 0.0.0.0:9876
2024.01.21 22:36:19:0001 [io-comp...] [INFO ] org.http4s.netty.server.NettyServerBuilder - Using NIO EventLoopGroup
2024.01.21 22:36:19:0001 [io-comp...] [INFO ] org.http4s.netty.server.NettyServerBuilder - Using NIO EventLoopGroup
2024.01.21 22:36:19:0002 [io-comp...] [INFO ] org.http4s.netty.server.NettyServerBuilder - Started Http4s Netty Server at http://[::]:9876/
2024.01.21 22:36:19:0002 [io-comp...] [INFO ] org.http4s.netty.server.NettyServerBuilder - Started Http4s Netty Server at http://[::]:19876/
You can now access the API at http://localhost:9876
and the admin server at http://localhost:19876
.
For example, to get the readiness porbe status, you can run:
$ curl http://localhost:19876/admin/probes/health | jq
{
"status": "pass",
"checks": [
{
"componentId": "db",
"componentType": "datastore",
"status": "pass"
}
]
}
Application Metadata
The infos
property of the App[F]
trait defines some metadata about your application.
You have two ways of defining it:
You can directly create an instance of AppInfo
:
val infos = AppInfo(
name = App.Name("Bookstore"),
version = App.Version("1.0.0"),
description = App.Description("A simple bookstore")
)
Or, if you are using the sbt-buildinfo plugin, you can use the BuildInfo
object.
In your build.sbt
, add the following lines to your project definition:
lazy val example = Project("pillars-example", file("modules/example"))
.enablePlugins(BuildInfoPlugin) // (1)
.settings(sharedSettings)
.settings(
name := "pillars-example", // (2)
description := "pillars-example is an example of application using pillars", // (3)
libraryDependencies ++= Dependencies.tests ++ Dependencies.migrationsRuntime, // (4)
buildInfoKeys := Seq[BuildInfoKey](name, version, description), // (5)
buildInfoOptions := Seq(BuildInfoOption.Traits("pillars.BuildInfo")), // (6)
buildInfoPackage := "example.build", // (7)
publish / skip := true,
tlMimaPreviousVersions := Set.empty,
libraryDependencySchemes ++= libDependencySchemes,
unusedCompileDependenciesFilter -= moduleFilter("org.typelevel", "scalac-compat-annotation")
)
.dependsOn(core, dbSkunk, flags, httpClient, dbMigrations)
1 | Enable the BuildInfo plugin |
2 | Define the name of your application |
3 | Define the description of your application |
4 | Declare the dependencies you want to use in your app. |
5 | Tell buildinfo to generate the BuildInfo object including at least name , description and version properties.
In this specific case, version is defined by the sbt-dynver plugin. |
6 | Configure BuildInfo to implement the pillars.BuildInfo trait.
It is required to use the BuildInfo object in your application. |
7 | Specify in which package will be generated the BuildInfo object. |
If you use the |
Then, you can use the BuildInfo
object in your application:
import example.build.BuildInfo
override val infos = BuildInfo.toAppInfo
override def run(): Run[IO, IO[Unit]] = ???
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.