> ## Content Index
> Fetch the complete content index at: https://honstain.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# REST in a Scalatra Service
- URL: https://honstain.com/rest-in-a-scalatra-service/
- Published: 2019-01-06T00:34:15.000Z
- Updated: 2026-06-21T00:33:27.000Z
- Description: Adding JSON support and tests to our basic Scalatra service.
- Author: Anthony Honstain
- Tags: Scalatra, Scala, #Import 2024-01-27 15:52

In our previous blog post we went through the official demo to create a basic Scalatra service [http://honstain.com/scalatra-giter8/](https://honstain.com/scalatra-giter8/). Now we want to expand that to implement a RESTful API. 

**WARNING** \- I am not a Scalatra expert, this blog is meant to document my journey of discovery as I work towards a more fully featured service.

## Adding Support for JSON

The best reference I found here is to follow the guide for [http://scalatra.org/guides/2.3/formats/json.html](http://scalatra.org/guides/2.3/formats/json.html?ref=honstain.com). By adding two new dependencies to the `build.sbt` file for scalatra-json and [json4s-jackson](http://json4s.org/?ref=honstain.com) we will have everything we need to get started.

I started out with an extremely basic implementation of a system to track inventory (there is no persistence layer set up and everything is kept in memory in a naive fashion).

![](https://honstain.com/content/images/2019/01/image.png)

```scala
import org.scalatra._
// JSON-related libraries
import org.json4s.{DefaultFormats, Formats}
// JSON handling support from Scalatra
import org.scalatra.json._

class ToyInventory extends ScalatraServlet with JacksonJsonSupport {

  protected implicit val jsonFormats: Formats = DefaultFormats

  before() {
    contentType = formats("json")
  }

  get("/") {
    InventoryData.all
  }

  post("/") {
    val newInventory = parsedBody.extract[Inventory]
    InventoryData.all = newInventory :: InventoryData.all
    newInventory
  }

}

case class Inventory(sku: String, qty: Int, description: String)

object InventoryData {

  var all = List(
    Inventory("ZL101", 1, "Black shoes"),
    Inventory("ZL102", 0, "Red dress"),
    Inventory("ZL103", 4, "Block of wood"),
  )
}

```

I won't try to duplicate the information in the [official guide](http://scalatra.org/guides/2.3/formats/json.html?ref=honstain.com), but we get support for JSON by mixing in the `JacksonJsonSupport` trait, configuring a `before()` filter, and using an implicit to specific desired format (a quick review of the README on [https://github.com/json4s/json4s](https://github.com/json4s/json4s?ref=honstain.com) could be helpful here).

The result here is that now we have a toy example that we can GET and POST to. I have included the Postman examples below (Postman is my preferred tool for interacting with RESTful services).

![](https://honstain.com/content/images/2019/01/image-2.png)

![](https://honstain.com/content/images/2019/01/image-1.png)

## Adding Tests to Our New Endpoints

At this stage I have created two endpoints for this toy inventory system:

- GET /
- POST /

If you used the giter8 template to generate the service, you will already have a basic test, you can use IntelliJ to run the tests for you (it gave me more than one choice, I wanted to use ScalaTest).

![](https://honstain.com/content/images/2019/01/image-3.png)

![](https://honstain.com/content/images/2019/01/image-4.png)

The test passes but it only verifies that the GET / endpoint returns an HTTP response code of 200\. Lets start by adding another test for the POST. I referenced this to convert my Inventory object to JSON [https://commitlogs.com/2017/01/14/serialize-deserialize-json-with-json4s-in-scala/](https://commitlogs.com/2017/01/14/serialize-deserialize-json-with-json4s-in-scala/?ref=honstain.com)

```Scala
import org.json4s.DefaultFormats
import org.scalatra.test.scalatest._
import org.json4s.jackson.Serialization.write

class ToyInventoryTests extends ScalatraFunSuite {

  implicit val formats = DefaultFormats

  addServlet(classOf[ToyInventory], "/*")

  test("GET / on ToyInventory should return status 200") {
    get("/") {
      status should equal (200)
    }
  }

  test("POST / on ToyInventory should return status 200") {
    post("/", write(Inventory("ZL104", 3, "Pine Block of wood"))) {
      status should equal (200)
    }
  }
}

```

What if we want to verify the response as well? We can add additional tests and validate the body of the response. You might chose to consolidate your tests more, I kept the status code check separate from the body check in an effort to help the reader.

```Scala
package org.bitbucket.honstain.app

import org.json4s.DefaultFormats
import org.scalatra.test.scalatest._
import org.json4s.jackson.Serialization.write

class ToyInventoryTests extends ScalatraFunSuite {

  implicit val formats = DefaultFormats

  addServlet(classOf[ToyInventory], "/*")

  test("GET / on ToyInventory should return status 200") {
    get("/") {
      status should equal (200)
    }
  }

  test("GET / on ToyInventory should return inventory list") {
    get("/") {
      val expectedResult = List(
        Inventory("ZL101", 1, "Black shoes"),
        Inventory("ZL102", 0, "Red dress"),
        Inventory("ZL103", 4, "Block of wood"),
      )
      body should equal (write(expectedResult))
    }
  }

  test("POST / on ToyInventory should return status 200") {
    val newInventory = Inventory("ZL104", 3, "Pine Block of wood")
    post("/", write(Inventory("ZL104", 3, "Pine Block of wood"))) {
      status should equal (200)
    }
  }

  test("POST / on ToyInventory should return newly created inventory") {
    val newInventory = Inventory("ZL104", 3, "Pine Block of wood")
    post("/", write(Inventory("ZL104", 3, "Pine Block of wood"))) {
      // Using a string representation of the expected Inventory for demonstration purposes.
      body should equal ("""{"sku":"ZL104","qty":3,"description":"Pine Block of wood"}""")
    }
  }
}

```

![](https://honstain.com/content/images/2019/01/image-5.png)

We have used the ScalatraFunSuite which supports a simple structure for tests, I would recommend taking a look at the ScalaTest documentation for FunSuite [http://www.scalatest.org/getting\_started\_with\_fun\_suite](http://www.scalatest.org/getting%5Fstarted%5Fwith%5Ffun%5Fsuite?ref=honstain.com)

You can source for these changes in the project repo here: [https://bitbucket.org/honstain/scalatra-example-blog/commits/ffda1e40fc8db9ae79beaea123d542459b6d3682](https://bitbucket.org/honstain/scalatra-example-blog/commits/ffda1e40fc8db9ae79beaea123d542459b6d3682?ref=honstain.com)

## References I found Helpful During This Guide:

- Scalatra Documentation: [http://scalatra.org/guides/2.3/formats/json.html](http://scalatra.org/guides/2.3/formats/json.html?ref=honstain.com)
- JSON
- [http://json4s.org/](http://json4s.org/?ref=honstain.com)
- [https://github.com/json4s/json4s](https://github.com/json4s/json4s?ref=honstain.com)
- Serialization [https://commitlogs.com/2017/01/14/serialize-deserialize-json-with-json4s-in-scala/](https://commitlogs.com/2017/01/14/serialize-deserialize-json-with-json4s-in-scala/?ref=honstain.com)
- Manipulating lists [https://alvinalexander.com/scala/how-add-elements-to-a-list-in-scala-listbuffer-immutable](https://alvinalexander.com/scala/how-add-elements-to-a-list-in-scala-listbuffer-immutable?ref=honstain.com)