< Iteration 4: Scala’s Type System
Advanced Scala Concepts
This covers chapters 16-18 in the O’Reilly book.
Understanding Implementation
Create an object HybridName with an apply and unapply method. The apply method should take in two strings, returning the strings with a hyphen joining them. Unapply should take in a string and return the two comprising pieces:
HybridName.apply("Sune", "Aznable") //This should return "Sune-Aznable"
HybridName.unapply("Bow-Ray") //This should return Some(Tuple2("Bow", "Ray"))
Now create a main method that pattern matches over a String. If either of the names in the given String is your last name, return true. Otherwise, return false.
Scala Koans
Before you move onto the milestone project revisions, work through the interactive Scala Koans from 47 Degrees. At this point, these should be simple. If you have issues with any of the exercises here, you know where you need to focus before moving on. Take notes and bring them to your mentor to work out a study plan.
Milestone Project
Now that your project has most of the functionality required, it’s time to serve it via an API.
You must fulfill several possible calls from the user by providing your own restful api. We use Spray to create RESTful APIs, and it can be very simple to get running, but if you are familar with providing a server you can use any library or method you want. (Note: Spray makes heavy usage of akka so versions matter! Check here)
Regardless of how you output your data, your code needs to run as a service- that is, a user should be able to leave an instance of your code running and make search requests whenever they want. Your code should track its own history and be able to return all searches it has ever retrieved.
There are a handful of functions you will need to expose to your users, including retrieving, filtering, and calculating metrics.
And remember: no code is complete until it is covered by unit tests.
Required Functionality
Your search repository must be able to promptly return searches even when it is running large analysis behind the scenes. This might mean running your analytics in the background whenever your service is running, or perhaps you’ll just run that request every time someone asks for stats. Think about performance and how you could scale your code- are you allowing hundreds of users to pull from one instance of your service, or does it require each user to produce their own instances? How would this affect latency introduced by HTTP calls?
Your API should return JSON for results. By now you have experience consuming JSON, and creating it should be relatively simple. The library you used in the last iteration should continue to serve you here.
You will be providing the following endpoints:
GET /pingReturns the string “Pong” to ensure the service is up.
POST /create_userCreates a new user and adds them to the DB. Takes in new credentials like:
{ "username": "username", "password": "password" }A 200 HTTP Status Code should be returned if there was no existing user with the given password and the request was successful, and a 403 HTTP Status Code if the user already exists.
POST /change_passwordCreates a new user and adds them to the DB. Takes in new credentials like:
{ "username": "username", "oldPassword": "oldPass", "newPassword": "different!" }A 200 HTTP Status Code should be returned if there was an existing user with the given oldPassword, the newPassword was a different string than the old, and the request was successful. Otherwise, a 403 HTTP Status Code should be returned.
POST /search?q=:searchStringExecutes a search for a user. Takes in JSON containing credentials like:
{ "username": "username", "password": "password" }
Returns JSON containing all results for the given string in the following format:
```json
{
"results": [
{
"name" : "SearchString Result Name"
"description" : "Description of given result"
},
{
"name" : "SearchString Result Name The Second"
"description" : "Description of second result"
}
]
}
```
Of course, you will need to keep track of this user's new search in your repository. You may store duplicate searches however you like, but you must track not only what searches the user has executed, but how many times they have executed them.
If the request either does not match an existing user, or does not match the given user's password, you should return a [403 HTTP Status Code](https://en.wikipedia.org/wiki/HTTP_403). You might have noticed that this is a somewhat inefficient form of security. You're correct, but we'll get there later.
- `GET /search_terms`
Returns JSON containing every search term used by every user. This should not contain duplicates, and simply be a list of all search terms attempted by users in the following format:
```json
{
"searches": [
"term" : "term1",
"term" : "term2"
]
}
POST /search_termsReturns search terms for a single user, provided authentication via JSON as above.
Analysis of Content
You’ll also need to provide endpoints to the analytic functions you created back in iteration 2.
GET /most_common_searchReturns the most common search term across all users. This should return a list, in case more than one term is tied for first place, as in the searchTerms endpoint.
POST /most_common_searchReturns the most common search term for a single user, taking validation JSON as above and returning a list of search terms.
With this, you have completed your basic Scala training! Circle up with your mentor or supervisor and you’ll be assigned to a team, where you can start digging into production code.