You can declare a dependency on Cask with the following using
directive:
//> using dep "com.lihaoyi::cask::0.9.2"
In your build.sbt
, you can add a dependency on Cask:
lazy val example = project.in(file("example"))
.settings(
scalaVersion := "3.4.2",
libraryDependencies += "com.lihaoyi" %% "cask" % "0.9.2",
fork := true
)
In your build.sc
, you can add a dependency on Cask:
object example extends RootModule with ScalaModule {
def scalaVersion = "3.3.3"
def ivyDeps = Agg(
ivy"com.lihaoyi::cask::0.9.2"
)
}
Serving a static file
An endpoint is a specific URL where a particular webpage can be accessed. In Cask, an endpoint is a function returning the webpage data, together with an annotation describing its URL.
To create an endpoint serving static files, we need two things: an HTML file with the page content and a function that points to that file.
Create a minimal HTML file named hello.html
with the following contents.
<!doctype html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
Place it in the resources
directory.
example
├── Example.scala
└── resources
└── hello.html
example
└──src
└── main
├── resources
│ └── hello.html
└── scala
└── Example.scala
example
├── src
│ └── Example.scala
└── resources
└── hello.html
The @cask.staticFiles
annotation specifies at which path the webpage will be available. The endpoint function returns
the location of the file.
object Example extends cask.MainRoutes {
@cask.staticFiles("/static")
def staticEndpoint(): String = "src/main/resources" // or "resources" if not using SBT
initialize()
}
object Example extends cask.MainRoutes:
@cask.staticFiles("/static")
def staticEndpoint(): String = "src/main/resources" // or "resources" if not using SBT
initialize()
In the example above, @cask.staticFiles
instructs the server to look for files accessed at the /static
path in the
src/main/resources
directory. Cask will match any subpath coming after /static
and append it to the directory path.
If you access the /static/hello.html
file, it will serve the file available at src/main/resources/hello.html
.
The directory path can be any path available to the server, relative or not. If the requested file cannot be found in the
specified location, the server will return a 404 response with an error message.
The Example
object inherits from the cask.MainRoutes
class. It provides the main function that starts the server. The initialize()
method call initializes the server routes, i.e., the association between URL paths and the code that handles them.
Using the resources directory
The @cask.staticResources
annotation works in the same way as the @cask.staticFiles
used above, with the difference that
the path returned by the endpoint method describes the location of files inside the resources directory. Since the
previous example conveniently used the resources directory, it can be simplified with @cask.staticResources
.
object Example extends cask.MainRoutes {
@cask.staticResources("/static")
def staticEndpoint(): String = "."
initialize()
}
object Example extends cask.MainRoutes:
@cask.staticResources("/static")
def staticEndpoint(): String = "."
initialize()
In the endpoint method, the location is set to "."
, telling the server that the files are available directly in the
resources directory. In general, you can use any nested location within the resources directory. For instance, you could opt
for placing your HTML files in the static
directory inside the resources directory or using different directories to sort out
files used by different endpoints.
Running the example
Run the example with the build tool of your choice.
In the terminal, the following command will start the server:
scala run Example.scala
In the terminal, the following command will start the server:
sbt example/run
In the terminal, the following command will start the server:
./mill run
The example page will be available at http://localhost:8080/static/hello.html.