Scala’s Collections and Type System
This covers chapters 12-15 in the O’Reilly book.
If the academic language over the type system is proving taxing, Heather Miller’s talk Academese to English does a great job of cutting through some of the jargon.
Complete the first few of the 99 Scala Problems. You only need to complete 1-25, but try 26-28. Do not use Scala’s built in functions to complete this.
After this, you’ll create your own implementation of several List functions.
Be sure to push both exercises up to the internal Git!
At this point, you should be comfortable with many of the collections you’ll find in Scala’s Standard Library. Look over the performance characteristics of the most common collections you’ll see. For deeper reading, we recommend this blog post from 47 Degrees. At this point, you should be considering the best collection for a given situation rather than defaulting to List.
Http Client
To familiarize yourself with HTTP read this paper.
Create a Scala wrapper of an http client and implement some methods that will make it easier for you to use on a RESTful API.
You can use any HTTP Client you wish. As a starting point, here are a few HTTP clients used in Banno’s code base:
- http4s
- Apache HTTP Client
- Async HTTP Client
- Google’s HTTP Client
- Finally, you can just find your own way- you only need one HTTP client to start, which means you can leverage any experience you have with other clients - or even just curl from code. What you use doesn’t matter, so long as you can back up your reasoning for why you chose it.
Your HTTP client should be used to implement these methods for completing the standard RESTful commands Get and Post:
case class HttpResponse(header: String, body: String, statusCode: Int)
trait HttpClient {
def executeHttpPost(url: String, body: Map[String,String]): HttpResponse
def executeHttpGet(url: String): HttpResponse
}
These fields are a suggestion. If you feel they need to be changed you are welcome to. This is something that will go into your own project and as such your own discretion should be used to write it. This is simply a starting point.
Make sure you have tests around your code and have gone over it with your mentor. This will be useful for later projects.
Milestone Project
It’s time to get some meat into your project. You’ll be executing a user’s searches via DuckDuckGo’s RESTful Instant Answer API. You can execute the requests outlined via your HTTP client wrapper, and their site throws out some example queries to view how your results are returned.
For each search you’ll still want to hold onto the search term and the result. You’ll see that the results returned from DuckDuckGo in the RelatedTopics field contain both of these pieces in a single field. You’ll need to find a way to parse this string and separate them out in your models.
You’ll also be dealing with something new here: your results will be returned in json. JSON represents structures serialized as Strings, and is one of the most common ways to provide content out of an API. There are a number of ways to parse these, including our own jsonz library, sjson, and the ever-popular Jackson.
Finally, you no doubt already have a method for storing all of your users. Perhaps it’s just a data structure in your main file, or perhaps you’ve created something more complex. At this point, you should be considering how to architect your User Repository with a mind toward easily swapping out what kind of repository you’re using. Consider this a starting point:
trait Repository[A] {
def getAll: Seq[A]
def get(id: String): Option[A]
def create(x: A): Option[A]
def update(x: A): Option[A]
def delete(x: A): Option[A]
}
Store the data however you see fit. You might use a file to persist users across executions of your program, you might store them in memory, you might even peek ahead and check out this PostgreSQL thing. If not, don’t worry; you’ll get there.
You might be wondering how a user will be able to interact with your program, now that it has some real functionality. Next iteration, you’ll be creating your own RESTful API.