Thorium Server

Creating a server

First, under the main method in Main.scala; the main method should create a WebServer instance, add the services or controllers, and start the server.

In the example below, the service is hosted at the port 8080 with a dummy service returning "Welcome to Thorium!". 

import com.greenfossil.thorium.{*, given}

@main def start: Unit = Server(8080)
       .addHttpService("/", Action(request => "Welcome to Thorium!"))
       .start()

To run the server, run the main method in IntelliJ IDEA or use the run command in your sbt shell.

Check if the server is running, navigate to a browser and type in http://localhost:8080 in the url to access the page. 

Last modified on 10/11/2023, 5:04 pm

Creating a controller

Proceed to the controllers folder and open the SimpleController file. You should find the following code inside as shown below:

import com.linecorp.armeria.server.annotation.{Get, Param}

object SimpleController:
  @Get("/sayHello/:name")
  def sayHello(@Param name: String) = s"Hello $name"

An alternative way to write the controller method above is shown in the example below:

import com.greenfossil.thorium.Action
import com.linecorp.armeria.server.annotation.{Get, Param}

object SimpleController:
  @Get("/sayHello/:name")
  def sayHello(@Param name: String) = Action: request => 
    s"Hello $name"

In the main method, remove the dummy service, do note that the route http://localhost:8080 would no longer be accessible as the service is removed. Add the new controller in order to access the route defined inside the new controller. 

import com.greenfossil.thorium.{*, given}
import controllers.SimpleController

@main def start: Unit =
  Server(8080)
    .addServices(SimpleController)
    .start()
Restart the server for the following changes to take effect. Navigate to a browser and type in http://localhost:8080/sayHello/john in the url. It should now reflect Hello john instead. 

Last modified on 22/11/2023, 3:00 pm

Redirect

To redirect a request, use the Redirect method. An example is shown below.

import com.greenfossil.thorium.{*, given}
import com.linecorp.armeria.server.annotation.{Get, Param}

object SimpleController:
  @Get("/sayHello/:name")
  def sayHello(@Param name: String) = Action: request =>
    s"Hello $name"

  @Get("/redirect")
  def redirect = Action: request => 
    Redirect(sayHello("User"))

Last modified on 22/11/2023, 3:02 pm

Handling POST Requests

To handle submitted data from POST requests, you can use the data-mapping library which is bundled with web-server.

Shown below is a simple form that accepts two fields:

import com.greenfossil.data.mapping.Mapping
import com.greenfossil.data.mapping.Mapping.*

val userForm: Mapping[(String, String)] = tuple(
  "firstname" -> text,
  "lastname" -> text
)

Create a POST controller method and use bindFromRequest() to retrieve data from POST request.

@Post("/createUser")
def createUser = Action:
  implicit request =>
  userForm.bindFromRequest().fold(
    errorForm => 
      val errorMessage = errorForm.errors.map:
        error =>
          s"Field ${error.key} has error: ${error.message}"
        .mkString(". ")
      BadRequest(errorMessage),
    (firstname, lastname) =>
      Ok(s"Hello, $firstname, $lastname!")
  )

To test this endpoint, you can use this curl command in the terminal:

curl -d firstname=john -d lastname=doe  http://localhost:8080/createUser

If you see the server response with the text "Hello, john, doe!", it means the form has retrieved data successfully.

This library can also handle POST requests with JSON content type. This command will give you the same result:
curl -H 'Content-Type: application/json' -d '{"firstname":"john", "lastname":"doe"}'  http://localhost:8080/createUser
Last modified on 22/11/2023, 3:04 pm