As our website grows and people can log in, add books to their own collection, a need to access this collection on their mobile arises.
When starting the mobile application and entered the correct login information, a request is being made to get the list of authors.
Clicking on an author will get a list of books from that author that the user owns, clicking on a book shows the details.
So the first query that needs implementing is: Give me a list of Authors for which the current user owned books
Given the Following Mapper Data Model:
Author <- (1) -> Book <- (2) -> User
(1) An Author can have more books while books can be written by multiple authors (N-N)
(2) A user can own multiple books, while a book can have multiple owners (N-N)
note: When successfully authenticating in a user his API key is returned which is used in all other requests
Below we will see the code that executes this query
what happens line by line is this:
- Line4: we get a list of books for the current user
- Line5: we map the colllection to one that contains the authors for each book, the result is a list of lists of authors List[List[Author]]
- Line6: foldLeft applies the method to each element in the list, from left to right, as the method ++ means adding two list’s together, we’ll end up with one list containing all authors
- Line7: distinct removes any duplicates in there
- Line8: We sort the list on the author’s lastName property
- Line9: we map it to a List of Xml fragments
Scala’s inline XML support allows us to simple put the Authors tag around it.
The second case does the same but gives a JSON response
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | serve { case "api" :: key :: "user" :: "authors" :: "all" :: _ XmlGet _ => { <Authors> { Book.findAll(In(Book.id ,BookUser.book, By(BookUser.user, getUserIdFromKey(key)))) .map(book => { book.authors.get }) .foldLeft(List[Author]())(_ ++ _) .distinct .sortWith((a1:Author, a2:Author) => a1.lastName.is < a2.lastName.is) .map(author => author.toXml) } </Authors> } case "api" :: key :: "user" :: "authors" :: "all" :: _ JsonGet _ => { JsonWrapper ("Authors", { Book.findAll(In(Book.id ,BookUser.book, By(BookUser.user, getUserIdFromKey(key)))) .map(book => { book.authors.get }) .foldLeft(List[Author]())(_ ++ _) .distinct .sortWith((a1:Author, a2:Author) => a1.lastName.is < a2.lastName.is) .map(author => author.toJson) }) } } //helper method def getUserIdFromKey(key:String):Long = { User.find(By(User.key, key) match { case Full(user) => user.id case (_) => 0 } } |


