{"@attributes":{"version":"2.0"},"channel":{"title":"Spaghetti and Hammers - Articles","description":"Personal site of Pedro Rijo (@pedrorijo91). Writing about Scala, Java, Functional Programming, git, and whatever I find time to learn about.","link":"https:\/\/pedrorijo.com","item":[{"title":"Some of my favorite programming principles","description":"Sharing some of my favorite programming principles","pubDate":"Sun, 01 Feb 2026 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/principles\/","guid":"https:\/\/pedrorijo.com\/blog\/principles\/"},{"title":"The Hidden Downsides of Daily Stand-ups","description":"A critical look at daily stand-ups and how they often disrupt focus, delay progress, and become performative rituals instead of productive meetings.","pubDate":"Wed, 09 Apr 2025 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/daily\/","guid":"https:\/\/pedrorijo.com\/blog\/daily\/"},{"title":"Recommended books","description":"Some technical books I would recommend every engineer to read","pubDate":"Sat, 15 Mar 2025 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/books\/","guid":"https:\/\/pedrorijo.com\/blog\/books\/"},{"title":"To be more Catholic than the Pope","description":"When to follow the rules and when to break them","pubDate":"Sat, 11 Jan 2025 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/pope\/","guid":"https:\/\/pedrorijo.com\/blog\/pope\/"},{"title":"My Hands-On Experience with Gen-AI","description":"Some thoughts on my experience using the latest Gen-AI tools","pubDate":"Tue, 24 Dec 2024 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/gen-ai\/","guid":"https:\/\/pedrorijo.com\/blog\/gen-ai\/"},{"title":"Bloom Filters","description":"Bloom Filters as space-efficient alternatives to Sets","pubDate":"Fri, 12 Nov 2021 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/bloom-filters\/","guid":"https:\/\/pedrorijo.com\/blog\/bloom-filters\/"},{"title":"Using Java Service Loader","description":"Using Java Service Loader to allow pluggable code","pubDate":"Mon, 23 Aug 2021 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/java-service-loader\/","guid":"https:\/\/pedrorijo.com\/blog\/java-service-loader\/"},{"title":"Load testing using k6","description":"Load testing a service using k6","pubDate":"Thu, 08 Jul 2021 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/load-test-k6\/","guid":"https:\/\/pedrorijo.com\/blog\/load-test-k6\/"},{"title":"Scala tutorials in Baeldung","description":"Scala tutorials now in Baeldung","pubDate":"Thu, 11 Mar 2021 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-tutorials-baeldung\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-tutorials-baeldung\/"},{"title":"What is a good developer?","description":"How to be a good developer - beyond the technical skills","pubDate":"Sat, 07 Nov 2020 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/what-is-a-good-developer\/","guid":"https:\/\/pedrorijo.com\/blog\/what-is-a-good-developer\/"},{"title":"Newsletter","description":"<p><span class=\"dropcap\">I<\/span> have been thinking for long time in creating a newsletter. I made an <a href=\"\/feed.xml\">rss feed<\/a> since day 1, but I know some people prefer newsletters.<\/p>\n\n<p>So you can now sign-up to receive new posts on your inbox. No spam, just an email whenever a new blog post is published. And don\u2019t worry, you\u2019ll get 1 email per week at most.<\/p>\n\n<p align=\"center\">\n <a href=\"https:\/\/mailchi.mp\/f9d5cd479369\/pedrorijo91\" class=\"button\">Sign-up newsletter here!<\/a> \n <p>\n<\/p><\/p>\n","pubDate":"Wed, 15 Apr 2020 14:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/newsletter\/","guid":"https:\/\/pedrorijo.com\/blog\/newsletter\/"},{"title":"Implementing Authentication on Play Framework","description":"Implementing User Authentication on Scala Play Framework","pubDate":"Mon, 13 Apr 2020 18:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-play-auth\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-play-auth\/"},{"title":"When 1 + 1 = 3","description":"How to make Java saying 1 + 1 = 3 by messing with Integer cache","pubDate":"Tue, 24 Mar 2020 18:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/java-integer-cache\/","guid":"https:\/\/pedrorijo.com\/blog\/java-integer-cache\/"},{"title":"My journey into React","description":"My experience coming from the JVM into front-end development with React","pubDate":"Sun, 01 Dec 2019 15:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/my-journey-into-react\/","guid":"https:\/\/pedrorijo.com\/blog\/my-journey-into-react\/"},{"title":"Type safe builder pattern","description":"How to create a type safe builder pattern","pubDate":"Tue, 17 Sep 2019 18:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/typesafe-builder\/","guid":"https:\/\/pedrorijo.com\/blog\/typesafe-builder\/"},{"title":"First steps into RabbitMQ","description":"Beginners tutorial on why and how to use RabbitMQ with Scala examples","pubDate":"Tue, 18 Jun 2019 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-rabbitmq\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-rabbitmq\/"},{"title":"Play Framework and Slick example updated","description":"The updated version of the Play Framework, Slick, and MySQL tutorial and demo application. Now for Play 2.7.X","pubDate":"Tue, 23 Apr 2019 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/play-slick-updated\/","guid":"https:\/\/pedrorijo.com\/blog\/play-slick-updated\/"},{"title":"An intro to Mutation Testing - or why coverage sucks","description":"A intro to Mutation Testing, a technique that has become robust enough to be seen as a reliable alternative to Code Coverage as the de facto metric for assessing your unit tests quality.","pubDate":"Thu, 14 Feb 2019 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/intro-mutation\/","guid":"https:\/\/pedrorijo.com\/blog\/intro-mutation\/"},{"title":"Strings are not the type you are looking for","description":"Why use statically typed languages when all of your types are Strings? Forget about Primitive Obsession and leverage the type system for code correctness","pubDate":"Fri, 31 Aug 2018 19:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/strings-as-types\/","guid":"https:\/\/pedrorijo.com\/blog\/strings-as-types\/"},{"title":"Are Scala Streams really lazy?","description":"Are Scala Streams really lazy?","pubDate":"Sun, 01 Jul 2018 21:30:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-streams\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-streams\/"},{"title":"Creating forms on your Play application - Part 2","description":"Advanced HTML forms in Play framework.","pubDate":"Tue, 20 Feb 2018 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/advanced-play-forms\/","guid":"https:\/\/pedrorijo.com\/blog\/advanced-play-forms\/"},{"title":"Creating forms on your Play application - Part 1","description":"How to create simple HTML forms in Play framework.","pubDate":"Thu, 01 Feb 2018 22:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/play-forms\/","guid":"https:\/\/pedrorijo.com\/blog\/play-forms\/"},{"title":"Why you should think twice before using Tuples","description":"Why you should think twice before using Scala Tuples. The problems of using tuples in Scala.","pubDate":"Thu, 30 Nov 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/tuples-are-evil\/","guid":"https:\/\/pedrorijo.com\/blog\/tuples-are-evil\/"},{"title":"Handling exceptions in Scala","description":"How to handle exceptions in Scala. try\/catch vs Try vs Catch[T]","pubDate":"Tue, 29 Aug 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-exceptions\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-exceptions\/"},{"title":"Git Workflow","description":"How to use Git? What is the best Git workflow? Hot to use git log? Solving merge conflicts. Git reset vs Git checkout. Third part of a series of git tutorials","pubDate":"Wed, 28 Jun 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/git-workflow\/","guid":"https:\/\/pedrorijo.com\/blog\/git-workflow\/"},{"title":"Scala interview questions","description":"Some basic, or not so basic, questions about Scala. Interview level questions. Preparing your next Scala interview.","pubDate":"Tue, 14 Mar 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-interview-questions\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-interview-questions\/"},{"title":"Functional Programmings concepts","description":"Functional Programming concepts. What is referential transparency? That are pure functions? What is idempotence? What is the Uniform Access Principle?","pubDate":"Mon, 20 Feb 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/fp-concepts\/","guid":"https:\/\/pedrorijo.com\/blog\/fp-concepts\/"},{"title":"Git Clone","description":"Getting started with Git. Git basic commands. Everything you need to know to start using Git in your personal projects. Second part of a series of tutorials","pubDate":"Tue, 31 Jan 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/git-clone\/","guid":"https:\/\/pedrorijo.com\/blog\/git-clone\/"},{"title":"Git Init","description":"Introduction to Git. What is Git? First part of a series of tutorials","pubDate":"Wed, 25 Jan 2017 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/git-init\/","guid":"https:\/\/pedrorijo.com\/blog\/git-init\/"},{"title":"Scala Enumerations - Return of the (Java) Jedi","description":"Second part of Scala enumerations, after some discussions. Looking at enumerations libs overheads, and Java enums as an alternative.","pubDate":"Mon, 12 Dec 2016 23:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-enums-part2\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-enums-part2\/"},{"title":"Scala Enumerations","description":"How to use enumerations in Scala? Is the native approach the best one? Which problems does it brings? Are there any interesting alternatives?","pubDate":"Mon, 05 Dec 2016 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-enums\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-enums\/"},{"title":"How to make the Scala compiler to review your code","description":"<p><span class=\"dropcap\">C<\/span>ode review has become <a href=\"https:\/\/blog.codinghorror.com\/code-reviews-just-do-it\/\">one of the most important (and used) techniques<\/a> when it comes to code quality. The code review process may have very different workflows and subtleties, but it is often driven around the following steps:<\/p>\n\n<ul>\n  <li>The developer responsible by the code (a new feature, a bug fix, a refactor, etc) sends his changes to other colleagues (in git it is called a patch, that can be transformed into a <a href=\"https:\/\/help.github.com\/articles\/using-pull-requests\/\">pull request<\/a>, <a href=\"http:\/\/docs.gitlab.com\/ce\/gitlab-basics\/add-merge-request.html\">merge request<\/a>, or any other name your Git repository hosting service calls it).<\/li>\n  <li>His colleagues will read his changes. As they read the code, they will approve the changes, or comment on some point in which they disagree or don\u2019t totally understand.<\/li>\n  <li>If there is any question, the author will clarify. If there\u2019s any controversial change for any reviewer a bigger discussion may take place, until all the involved developers agree with the changes.<\/li>\n  <li>When no more unsolved issues are present, the changes will be included in the main code.<\/li>\n<\/ul>\n\n<p align=\"center\"><img src=\"\/assets\/img\/code-review-cartoon.jpg\" alt=\"Code Review\" title=\"Code Review\" width=\"300px\" \/><\/p>\n\n<p>This process allows to detect most bugs before they go into productionBut most of those changes can be automated. Unfortunately, a <a href=\"http:\/\/blog.codacy.com\/2015\/04\/08\/20-of-code-review-comments-are-about-style-and-best-practices-2\/\">big part of the review comments have to do with code style and bad practices<\/a>. But most of those reviews can be automated, or at least the problems can be automatically detected.<\/p>\n\n<p>In order to reduce the time spent on the review process, several different solutions are available:<\/p>\n\n<ul>\n  <li>A <a href=\"https:\/\/github.com\/google\/styleguide\">formal code style<\/a>. Document and\/or provide <a href=\"https:\/\/github.com\/google\/styleguide\/commit\/0249a38579160e135cbd7eb5099898611683200e\">format settings<\/a> for the most used IDEs (which can be hard due to the wide range of available text editors\/IDEs).<\/li>\n  <li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Lint_(software)\">Linters<\/a> (static analysis tools). Language dependent, every major programming language has some static analysis tool\/linter available. <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_tools_for_static_code_analysis\">There are hundreds<\/a>. Furthermore, many online platforms are emerging which provide several static analysis tools making it easy to configure some rules across all your projects. One of them is <a href=\"https:\/\/www.codacy.com\/\">Codacy<\/a>.<\/li>\n  <li>Use the compiler flags itself. This technique is only valid for compiled languages, but compilers often include flags to check some code standards. <a href=\"https:\/\/gcc.gnu.org\/\">gcc<\/a> for instance provides the infamous <code class=\"language-plaintext highlighter-rouge\">-pedantic<\/code> and <code class=\"language-plaintext highlighter-rouge\">-Wall<\/code> among <a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc\/Warning-Options.html#Warning-Options\">many others<\/a>.<\/li>\n<\/ul>\n\n<p align=\"center\"><img src=\"\/assets\/img\/compiling.png\" alt=\"Code compiling\" title=\"Code compiling\" width=\"300px\" \/><\/p>\n\n<h3 id=\"how-can-the-scala-compiler-help-me\">How can the Scala compiler help me?<\/h3>\n\n<p>Just like gcc, the scala compiler has its own set of flags for detecting some undesired code patterns. Unfortunately, the list of available flags is a bit scattered, but you can find them by typing <code class=\"language-plaintext highlighter-rouge\">scalac -help<\/code>, <code class=\"language-plaintext highlighter-rouge\">scalac -X<\/code>, <code class=\"language-plaintext highlighter-rouge\">scalac -Xlint:help<\/code> and <code class=\"language-plaintext highlighter-rouge\">scalac -Y<\/code> (note that each command provides information about a different set of flags).<\/p>\n\n<p>To better understand the difference between all of those different options, check <a href=\"http:\/\/stackoverflow.com\/a\/38032455\/4398050\">this SO answer<\/a>.<\/p>\n\n<p>By typing <code class=\"language-plaintext highlighter-rouge\">scalac -X<\/code> you will get several interesting flags. My favourite is <code class=\"language-plaintext highlighter-rouge\">-Xfatal-warnings<\/code>, which will make the compilation fail if any warning is found. It is particularly useful to demand that you fix the issues. Otherwise it will be a question of time until your code base is full of warnings that someone decided that could be postponed.<\/p>\n\n<h3 id=\"which-flags-should-i-use\">Which flags should I use?<\/h3>\n\n<p>Well, it really depends on you, but here\u2019s my set of flags:<\/p>\n\n<h4 id=\"-deprecation\">-deprecation<\/h4>\n<p>Emit warning and location for usages of deprecated APIs.<\/p>\n\n<p>Because deprecated methods have a (good) reason to be deprecated, we should avoid using them<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">$<\/span> <span class=\"n\">cat<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Example<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"nd\">@deprecated<\/span><span class=\"o\">(<\/span><span class=\"s\">\"not safe, use m2 instead\"<\/span><span class=\"o\">,<\/span> <span class=\"s\">\"v.0.1.0\"<\/span><span class=\"o\">)<\/span> <span class=\"k\">def<\/span> <span class=\"nf\">m1<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"n\">x<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">test<\/span> <span class=\"k\">=<\/span> <span class=\"nf\">m1<\/span><span class=\"o\">(<\/span><span class=\"mi\">3<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n\n<span class=\"n\">$<\/span> <span class=\"n\">scalac<\/span> <span class=\"o\">-<\/span><span class=\"n\">deprecation<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span><span class=\"k\">:<\/span><span class=\"err\">5<\/span><span class=\"kt\">:<\/span> <span class=\"kt\">warning:<\/span> <span class=\"kt\">method<\/span> <span class=\"kt\">m1<\/span> <span class=\"kt\">in<\/span> <span class=\"kt\">object<\/span> <span class=\"kt\">Example<\/span> <span class=\"kt\">is<\/span> <span class=\"kt\">deprecated:<\/span> <span class=\"kt\">not<\/span> <span class=\"kt\">safe<\/span><span class=\"o\">,<\/span> <span class=\"n\">use<\/span> <span class=\"n\">m2<\/span> <span class=\"n\">instead<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">test<\/span> <span class=\"k\">=<\/span> <span class=\"nf\">m1<\/span><span class=\"o\">(<\/span><span class=\"mi\">3<\/span><span class=\"o\">)<\/span>\n             <span class=\"o\">^<\/span>\n<span class=\"n\">one<\/span> <span class=\"n\">warning<\/span> <span class=\"n\">found<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"-xfatal-warnings\">-Xfatal-warnings<\/h4>\n<p>Fail the compilation if there are any warnings.<\/p>\n\n<h4 id=\"-xlintmissing-interpolator\">-Xlint:missing-interpolator<\/h4>\n<p>A string literal appears to be missing an interpolator id.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">$<\/span> <span class=\"n\">cat<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Example<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">transformation<\/span><span class=\"o\">(<\/span><span class=\"n\">str<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"s\">\"This_is_my_str_transformed_ $str _END\"<\/span>\n\n<span class=\"o\">}<\/span>\n\n<span class=\"n\">$<\/span> <span class=\"n\">scalac<\/span> <span class=\"o\">-<\/span><span class=\"nc\">Xlint<\/span><span class=\"k\">:<\/span><span class=\"kt\">missing-interpolator<\/span> <span class=\"kt\">Example.scala<\/span>\n<span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span><span class=\"k\">:<\/span><span class=\"err\">3<\/span><span class=\"kt\">:<\/span> <span class=\"kt\">warning:<\/span> <span class=\"kt\">possible<\/span> <span class=\"kt\">missing<\/span> <span class=\"kt\">interpolator:<\/span> <span class=\"kt\">detected<\/span> <span class=\"kt\">interpolated<\/span> <span class=\"kt\">identifier<\/span> <span class=\"kt\">`$str`<\/span>\n  <span class=\"kt\">def<\/span> <span class=\"kt\">transformation<\/span><span class=\"o\">(<\/span><span class=\"kt\">str:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span> <span class=\"o\">=<\/span> <span class=\"s\">\"This_is_my_str_transformed_ $str _END\"<\/span>\n                                    <span class=\"o\">^<\/span>\n<span class=\"n\">one<\/span> <span class=\"n\">warning<\/span> <span class=\"n\">found<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"-ywarn-unused-import\">-Ywarn-unused-import<\/h4>\n<p>Warn when imports are unused<\/p>\n\n<p>Unused imports increase the change of merging conflicts on CVS. Even worst, you may be importing some implicit into scope, that is not currently being used, but may start to be used when you add some code, without you even noticing.<\/p>\n\n<h4 id=\"-ywarn-unused\">-Ywarn-unused<\/h4>\n<p>Warn when local and private vals, vars, defs, and types are unused.<\/p>\n\n<p>If you have unused vals, vars, defs, or types in your code, there is a big change that you may have a bug. While sometimes these warnings are just a consequence of a refactor, without any big problem besides useless computation, they may indicate you are passing the wrong argument to some function.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">$<\/span> <span class=\"n\">cat<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Example<\/span> <span class=\"o\">{<\/span>\n\n <span class=\"k\">def<\/span> <span class=\"nf\">method<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n   <span class=\"k\">val<\/span> <span class=\"nv\">y<\/span> <span class=\"k\">=<\/span> <span class=\"mi\">4<\/span>\n\n   <span class=\"nf\">aux<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span><span class=\"o\">)<\/span>\n <span class=\"o\">}<\/span>\n\n <span class=\"k\">def<\/span> <span class=\"nf\">aux<\/span><span class=\"o\">(<\/span><span class=\"n\">y<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"n\">y<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">4<\/span>\n\n<span class=\"o\">}<\/span>\n\n<span class=\"n\">$<\/span> <span class=\"n\">scalac<\/span> <span class=\"o\">-<\/span><span class=\"nc\">Ywarn<\/span><span class=\"o\">-<\/span><span class=\"n\">unused<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span><span class=\"k\">:<\/span><span class=\"err\">4<\/span><span class=\"kt\">:<\/span> <span class=\"kt\">warning:<\/span> <span class=\"kt\">local<\/span> <span class=\"kt\">val<\/span> <span class=\"kt\">in<\/span> <span class=\"kt\">method<\/span> <span class=\"kt\">method<\/span> <span class=\"kt\">is<\/span> <span class=\"kt\">never<\/span> <span class=\"kt\">used<\/span>\n   <span class=\"k\">val<\/span> <span class=\"nv\">y<\/span> <span class=\"k\">=<\/span> <span class=\"mi\">4<\/span>\n       <span class=\"o\">^<\/span>\n<span class=\"n\">one<\/span> <span class=\"n\">warning<\/span> <span class=\"n\">found<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"-ywarn-dead-code\">-Ywarn-dead-code<\/h4>\n<p>Warn when dead code is identified.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">$<\/span> <span class=\"n\">cat<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Example<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">m<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Unit<\/span> <span class=\"o\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nf\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"step1\"<\/span><span class=\"o\">)<\/span>\n    <span class=\"k\">return<\/span>\n    <span class=\"nf\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"step2\"<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n\n<span class=\"o\">}<\/span>\n\n<span class=\"n\">$<\/span> <span class=\"n\">scalac<\/span> <span class=\"o\">-<\/span><span class=\"nc\">Ywarn<\/span><span class=\"o\">-<\/span><span class=\"n\">dead<\/span><span class=\"o\">-<\/span><span class=\"n\">code<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span><span class=\"k\">:<\/span><span class=\"err\">5<\/span><span class=\"kt\">:<\/span> <span class=\"kt\">warning:<\/span> <span class=\"kt\">dead<\/span> <span class=\"kt\">code<\/span> <span class=\"kt\">following<\/span> <span class=\"kt\">this<\/span> <span class=\"kt\">construct<\/span>\n    <span class=\"k\">return<\/span>\n    <span class=\"o\">^<\/span>\n<span class=\"n\">one<\/span> <span class=\"n\">warning<\/span> <span class=\"n\">found<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"-ywarn-numeric-widen\">-Ywarn-numeric-widen<\/h4>\n<p>Warn when numerics are widened.<\/p>\n\n<p><a href=\"http:\/\/www.scala-lang.org\/files\/archive\/spec\/2.11\/06-expressions.html#numeric-widening\">Numeric widening<\/a> is an implicit conversion between two numbers of different types (Int and Double, for instance) useful for many cases, but it may be an <a href=\"https:\/\/groups.google.com\/d\/msg\/scala-internals\/Gi-54GeWv-M\/vy1fjqE0FosJ\">huge source of bugs<\/a><\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">$<\/span> <span class=\"n\">cat<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Example<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">m<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Double<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nf\">println<\/span><span class=\"o\">(<\/span><span class=\"n\">s<\/span><span class=\"s\">\"x is: $x\"<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">caller<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"k\">val<\/span> <span class=\"nv\">i<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span>\n    <span class=\"nf\">m<\/span><span class=\"o\">(<\/span><span class=\"n\">i<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n\n<span class=\"o\">}<\/span>\n\n<span class=\"n\">$<\/span> <span class=\"n\">scalac<\/span> <span class=\"o\">-<\/span><span class=\"nc\">Ywarn<\/span><span class=\"o\">-<\/span><span class=\"n\">numeric<\/span><span class=\"o\">-<\/span><span class=\"n\">widen<\/span> <span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span>\n<span class=\"nv\">Example<\/span><span class=\"o\">.<\/span><span class=\"py\">scala<\/span><span class=\"k\">:<\/span><span class=\"err\">9<\/span><span class=\"kt\">:<\/span> <span class=\"kt\">warning:<\/span> <span class=\"kt\">implicit<\/span> <span class=\"kt\">numeric<\/span> <span class=\"kt\">widening<\/span>\n    <span class=\"nf\">m<\/span><span class=\"o\">(<\/span><span class=\"n\">i<\/span><span class=\"o\">)<\/span>\n      <span class=\"o\">^<\/span>\n<span class=\"n\">one<\/span> <span class=\"n\">warning<\/span> <span class=\"n\">found<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<!-- ### Problems using flags\n\nUnfortunately, depending on which frameworks you are going to use, you will probably face some small bugs.  While I was trying to add my own set of flags to the compilation options I had to deal with some problems. Many of them due to some magic [Play](https:\/\/www.playframework.com\/) does.\n\n#### routes\n\nunused import  https:\/\/github.com\/playframework\/playframework\/pull\/6284\nunused val -> https:\/\/github.com\/playframework\/playframework\/issues\/6302 -->\n\n<h3 id=\"just-try-yourself\">Just try yourself<\/h3>\n\n<p>Now it\u2019s time for you to try some (all?) available flags and find your own set of options to include on the compilation. Be patient, as sometimes you may <a href=\"https:\/\/github.com\/playframework\/playframework\/pull\/6284\">struggle with some bugs<\/a>.<\/p>\n","pubDate":"Tue, 19 Jul 2016 23:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-compiler-review-code-warnings\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-compiler-review-code-warnings\/"},{"title":"Why I quit using Slack (during working hours)","description":"<p><span class=\"dropcap\">T<\/span>his month <a href=\"https:\/\/slack.com\/\">Slack<\/a> announced to <a href=\"http:\/\/www.nytimes.com\/2016\/04\/02\/technology\/slack-a-leading-unicorn-raises-200-million-in-new-financing.html?_r=0\">have raised $200M <\/a> on its most recent financing. At the same time I started to <strong>turn off Slack during working hours<\/strong>.<\/p>\n\n<h3 id=\"one-chat-to-rule-them-all\">One chat to rule them all<\/h3>\n\n<p>Slack (just as <a href=\"https:\/\/www.hipchat.com\/\">Hipchat<\/a>, and many other <a href=\"http:\/\/blog.capterra.com\/the-top-13-slack-alternatives\/\">alternatives<\/a>) are messaging apps for teams. If you are on a still small startup (&lt; 5 guys) maybe you don\u2019t have anything similar yet, but as you start to grow, you will fell the need for it. And as soon as you notice, Slack will be one of the most important tools you have.<\/p>\n\n<p>Besides communication, you will start using Slack for everything: from display <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Slack+Plugin\">CI builds information<\/a>, to <a href=\"https:\/\/slack.com\/apps\/A0GP9E18S-statsbot\">gather analytics<\/a>, to alert about <a href=\"https:\/\/www.zendesk.com\/apps\/slack\/\">user support tickets<\/a>, and many <a href=\"https:\/\/slack.com\/apps\">other possibilities<\/a>.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/jenkins-slack-notification2.png\" alt=\"Slack homepage\" title=\"Slack homepage\" width=\"500px\" \/><\/p>\n\n<p>And this usage of Slack is what it makes it so essential for your team. All your business information in the same place, organized into different channels with different topics. Probably one chat room for each development team, one chat room for marketing, another one for product, another for user support, one more for random talks between colleagues, yet another one for events, and so on.<\/p>\n\n<p>And while Slack <a href=\"https:\/\/slack.com\/is#try\">claims to boost productivity<\/a>, I have felt exactly the very opposite.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/slack-productivity.png\" alt=\"Slack homepage\" title=\"Slack homepage\" width=\"500px\" \/><\/p>\n\n<h3 id=\"too-much-communication\">Too much communication<\/h3>\n\n<p>Slacks generates too much noise. Even with a fairly small team. And it\u2019s easy to understand why: Just imagine that each team member (on a team with 10 people) will see something during the day that it finds worthy to be shared with the team. Now think about the number of times a colleague pings you for reviewing its pull request, or for asking you something important. Finally, just think about your integrations, and the number of notifications they will send.<\/p>\n\n<p>We can easily understand that Slack can popup a notification more than 30 times in a single day. In a 8 hours day this translates to a new notification\/distraction on your screen roughly at <strong>every 20 minutes<\/strong>.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/slack-notification.png\" alt=\"Slack notification\" title=\"Slack notification\" width=\"500px\" \/><\/p>\n\n<p>It makes it nearly impossible to work while focused on anything. Of course you can <a href=\"https:\/\/get.slack.help\/hc\/en-us\/articles\/201895138-Understanding-Slack-notifications\">customize notifications<\/a> so you don\u2019t get a popup every time someone writes something. I have set popups to only when I am mentioned. And it really helped to stop the flood of notifications.<\/p>\n\n<p>Still, I have OCD regarding apps with the small red dot on the dock :)<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/slack-dock-notification.png\" alt=\"Slack dock notification\" title=\"Slack dock notification\" width=\"500px\" \/><\/p>\n\n<h3 id=\"goodbye-slack\">Goodbye Slack<\/h3>\n\n<p>Now the first thing I do when I get to the office is to shut down Slack. If there\u2019s something important I will be mentioned and get a notification on mobile\/email.<\/p>\n\n<p>And the first thing I do as soon as I exit the office is to open Slack. This way I can scroll Slack, reading the jokes, the articles and blog posts someone posted, and keep alert if some problem arises.<\/p>\n\n<p>All of this without getting disturbed when I really need to be focused.<\/p>\n","pubDate":"Wed, 13 Apr 2016 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/slack-quit\/","guid":"https:\/\/pedrorijo.com\/blog\/slack-quit\/"},{"title":"Signing Git commits","description":"<p><span class=\"dropcap\">L<\/span>ast week GitHub released another new feature: <a href=\"https:\/\/github.com\/blog\/2144-gpg-signature-verification\">GPG signature verification<\/a>.<\/p>\n\n<p>While it may seem something new, <a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Signing-Your-Work\">Git already supports signing commits and tags with GPG <\/a>. Still, GitHub turned easier to verify if the commit is signed by the author, introducing a badge next to the commit UUID.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/github-gpg-example.png\" alt=\"GitHub verified commit\" title=\"GitHub verified commit\" width=\"500px\" \/><\/p>\n\n<h3 id=\"how-to-sign-my-own-commits\">How to sign my own commits<\/h3>\n\n<p>If you want GitHub to display your verified commits there are a couple of steps required. <a href=\"https:\/\/help.github.com\/articles\/generating-a-gpg-key\/\">GitHub provides a very good explanation on that<\/a>.<\/p>\n\n<ol>\n  <li>Assuming you don\u2019t have a GPG key yet, you need to <a href=\"https:\/\/help.github.com\/articles\/generating-a-new-gpg-key\/\">generate a new one<\/a>.<\/li>\n  <li>Now that you have a GPG key, <a href=\"https:\/\/help.github.com\/articles\/adding-a-new-gpg-key-to-your-github-account\/\">add it to GitHub<\/a>.<\/li>\n  <li><a href=\"https:\/\/help.github.com\/articles\/telling-git-about-your-gpg-key\/\">Configure git<\/a> to use your key<\/li>\n  <li>Start <a href=\"https:\/\/help.github.com\/articles\/signing-commits-using-gpg\/\">signing your commits<\/a>. It may be useful to define some <a href=\"https:\/\/git-scm.com\/book\/tr\/v2\/Git-Basics-Git-Aliases\">git aliases<\/a> to automate commit signature.<\/li>\n  <li>Push to your GitHub repository and see the verification badge.<\/li>\n<\/ol>\n\n<p align=\"center\"><img src=\"\/assets\/img\/github-gpg-commit-list.png\" alt=\"GitHub verified commit list\" title=\"GitHub verified commit list\" width=\"500px\" \/><\/p>\n\n<h3 id=\"what-about-now\">What about now?<\/h3>\n\n<p>Signing your commits is nice, but what for? Well, signing your work provides a guarantee that you did the work. But how can I verify that?<\/p>\n\n<p>Starting by git itself, the <code class=\"language-plaintext highlighter-rouge\">git log<\/code> command contains a <a href=\"https:\/\/git-scm.com\/book\/uz\/v2\/Git-Tools-Signing-Your-Work#Signing-Commits\">flag to show signatures<\/a><\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>$ git log --show-signatures\ncommit 5a9a6e3c5089ead02ce4ae4ee5f600626edf04b5\ngpg: Signature made Wed Apr  6 00:22:16 2016 WEST using RSA key ID F17F60C1\ngpg: Good signature from \"Pedro Rijo (pedrorijo91) &lt;some-email@mail.com&gt;\"\nAuthor: pedrorijo91 &lt;some-email@mail.com&gt;\nDate:   Wed Apr 6 00:22:16 2016 +0100\n\n    &lt;message&gt;\n\ncommit 5c644e7fee2d09dbc177f515c3936ff3e787373c\nAuthor: Pedro Rijo &lt;some-email@mail.com&gt;\nDate:   Wed Apr 6 00:20:06 2016 +0100\n\n    &lt;message&gt;\n<\/code><\/pre><\/div><\/div>\n\n<p>Git can be told to inspect and reject when merging a commit that does not carry a trusted GPG signature with the <code class=\"language-plaintext highlighter-rouge\">--verify-signatures<\/code> command:<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>$ git merge --verify-signatures &lt;non-verified-branch&gt;\nfatal: Commit ab06180 does not have a GPG signature.\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>$ git merge --verify-signatures &lt;verified-branch&gt;\nCommit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) &amp;lt;schacon@gmail.com&amp;gt;\nUpdating 5c3386c..13ad65e\nFast-forward\n README | 2 ++\n 1 file changed, 2 insertions(+)\n<\/code><\/pre><\/div><\/div>\n\n<p>Unfortunately it seems that GitHub doesn\u2019t offer pull-request\/commits protection with signature verification yet, so you would have to do it manually.<\/p>\n\n<p>In the meanwhile, have fun pranking your collegues who still doesn\u2019t sign their commits, <a href=\"https:\/\/github.com\/amoffat\/masquerade\">faking commits to look as they did it<\/a>.<\/p>\n\n<h3 id=\"more-about-gpg\">More about GPG<\/h3>\n\n<p>One question that will probably cross your mind, is how to distribute your public key, so that others can verify your commit signature. I googled a bit and I found <a href=\"http:\/\/security.stackexchange.com\/questions\/406\/how-should-i-distribute-my-public-key\">other people with the same question<\/a>. I found <a href=\"https:\/\/pgp.mit.edu\">pgp.mit.edu<\/a> nice and I used it myself to distribute <a href=\"https:\/\/pgp.mit.edu\/pks\/lookup?op=get&amp;search=0x840BD9EAF17F60C1\">my public key<\/a>. Another popular option seems to be <a href=\"https:\/\/keybase.io\/\">Keybase.io<\/a>, but I haven\u2019t tested yet.<\/p>\n","pubDate":"Fri, 08 Apr 2016 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/git-gpg\/","guid":"https:\/\/pedrorijo.com\/blog\/git-gpg\/"},{"title":"Saving JSON to Scala model - Part 2","description":"<p><span class=\"dropcap\">F<\/span>ollowing up <a href=\"https:\/\/pedrorijo.com\/blog\/scala-json\/\">my previous post on mapping json objects to Scala models<\/a>, it is time to present some more advanced use cases.<\/p>\n\n<p>In the past weeks I have found myself in cases where a little more \u2018magic\u2019 was needed:<\/p>\n\n<ol>\n  <li>Read dates from the json (<code class=\"language-plaintext highlighter-rouge\">org.joda.DateTime<\/code>)<\/li>\n  <li>Mapping primitive types (as <code class=\"language-plaintext highlighter-rouge\">Long<\/code>) to a custom <code class=\"language-plaintext highlighter-rouge\">case class<\/code><\/li>\n  <li>Nested objects<\/li>\n<\/ol>\n\n<h2 id=\"reading-dates-from-json-objects\">Reading dates from Json objects<\/h2>\n\n<p>Imagine you have a Json object, with a Unix timestamp field:<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"field\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"example field\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"date\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">1459014762000<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>How to map it?<\/p>\n\n<ul>\n  <li>Define the corresponding <code class=\"language-plaintext highlighter-rouge\">case class<\/code><\/li>\n  <li>Define a custom mapper. To read a DateTime one can use the default adapter provided by the library:<\/li>\n<\/ul>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">JsonExampleV1<\/span><span class=\"o\">(<\/span><span class=\"n\">field<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">date<\/span><span class=\"k\">:<\/span> <span class=\"kt\">DateTime<\/span><span class=\"o\">)<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">JsonExampleV1<\/span><span class=\"o\">{<\/span>\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">r<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">JsonExampleV1<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n    <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"field\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"date\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">DateTime<\/span><span class=\"o\">](<\/span><span class=\"nv\">Reads<\/span><span class=\"o\">.<\/span><span class=\"py\">DefaultJodaDateReads<\/span><span class=\"o\">)<\/span>\n    <span class=\"o\">)(<\/span><span class=\"nv\">JsonExampleV1<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Just test it:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">scala<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">jsonV1<\/span> <span class=\"k\">=<\/span> <span class=\"s\">\"\"\"{ \"field\": \"example field\", \"date\": 1459014762000 }\"\"\"<\/span>\n<span class=\"n\">jsonV1<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span> <span class=\"o\">=<\/span> <span class=\"o\">{<\/span> <span class=\"s\">\"field\"<\/span><span class=\"k\">:<\/span> <span class=\"err\">\"<\/span><span class=\"kt\">example<\/span> <span class=\"kt\">field<\/span><span class=\"err\">\"<\/span><span class=\"o\">,<\/span> <span class=\"s\">\"date\"<\/span><span class=\"k\">:<\/span> <span class=\"err\">1459014762000<\/span> <span class=\"o\">}<\/span>\n\n<span class=\"n\">scala<\/span><span class=\"o\">&gt;<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">parse<\/span><span class=\"o\">(<\/span><span class=\"n\">jsonV1<\/span><span class=\"o\">).<\/span><span class=\"py\">as<\/span><span class=\"o\">[<\/span><span class=\"kt\">JsonExampleV1<\/span><span class=\"o\">]<\/span>\n<span class=\"n\">res0<\/span><span class=\"k\">:<\/span> <span class=\"kt\">JsonExampleV1<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">JsonExampleV1<\/span><span class=\"o\">(<\/span><span class=\"n\">example<\/span> <span class=\"n\">field<\/span><span class=\"o\">,<\/span><span class=\"mi\">2016<\/span><span class=\"o\">-<\/span><span class=\"mi\">03<\/span><span class=\"o\">-<\/span><span class=\"mi\">26<\/span><span class=\"n\">T17<\/span><span class=\"k\">:<\/span><span class=\"err\">52<\/span><span class=\"kt\">:<\/span><span class=\"err\">42<\/span><span class=\"kt\">.<\/span><span class=\"err\">000<\/span><span class=\"kt\">Z<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2 id=\"reading-custom-case-classes\">Reading custom case classes<\/h2>\n\n<p>Now, if you do wrap your object identifiers for type safety, you will enjoy this:<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"id\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">91<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"data\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Some data\"<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>and the corresponding <code class=\"language-plaintext highlighter-rouge\">case classes<\/code>:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">MyIdentifier<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span>\n\n<span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">JsonExampleV2<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">MyIdentifier<\/span><span class=\"o\">,<\/span> <span class=\"n\">data<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now you just need to read the primitive type (<code class=\"language-plaintext highlighter-rouge\">Long<\/code>), and <code class=\"language-plaintext highlighter-rouge\">map<\/code> to your idenfier:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">object<\/span> <span class=\"nc\">JsonExampleV2<\/span> <span class=\"o\">{<\/span>\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">r<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">JsonExampleV2<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"id\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">].<\/span><span class=\"py\">map<\/span><span class=\"o\">(<\/span><span class=\"nc\">MyIdentifier<\/span><span class=\"o\">)<\/span> <span class=\"nf\">and<\/span>\n    <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"data\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span>\n    <span class=\"o\">)(<\/span><span class=\"nv\">JsonExampleV2<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Again, let\u2019s test it:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">scala<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">jsonV2<\/span> <span class=\"k\">=<\/span> <span class=\"s\">\"\"\" { \"id\": 91, \"data\": \"String data\" }\"\"\"<\/span>\n<span class=\"n\">jsonV2<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span> <span class=\"o\">=<\/span> <span class=\"s\">\" { \"<\/span><span class=\"n\">id<\/span><span class=\"s\">\": 91, \"<\/span><span class=\"n\">data<\/span><span class=\"s\">\": \"<\/span><span class=\"nc\">String<\/span> <span class=\"n\">data<\/span><span class=\"s\">\" }\"<\/span>\n\n<span class=\"n\">scala<\/span><span class=\"o\">&gt;<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">parse<\/span><span class=\"o\">(<\/span><span class=\"n\">jsonV2<\/span><span class=\"o\">).<\/span><span class=\"py\">as<\/span><span class=\"o\">[<\/span><span class=\"kt\">JsonExampleV2<\/span><span class=\"o\">]<\/span>\n<span class=\"n\">res1<\/span><span class=\"k\">:<\/span> <span class=\"kt\">JsonExampleV2<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">JsonExampleV2<\/span><span class=\"o\">(<\/span><span class=\"nc\">MyIdentifier<\/span><span class=\"o\">(<\/span><span class=\"mi\">91<\/span><span class=\"o\">),<\/span><span class=\"nc\">String<\/span> <span class=\"n\">data<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2 id=\"reading-nested-objects\">Reading nested objects<\/h2>\n\n<p>This one was motivated from a <a href=\"http:\/\/stackoverflow.com\/questions\/36202938\/scala-play-reads-parse-nested-json\/36210676\">Stackoverflow question<\/a>.<\/p>\n\n<p>Basically, the json answer contains an <code class=\"language-plaintext highlighter-rouge\">id<\/code> field, and a json array with friends, where each friend object is composed of another <code class=\"language-plaintext highlighter-rouge\">id<\/code> and a <code class=\"language-plaintext highlighter-rouge\">since<\/code> field.<\/p>\n\n<p>I will present two options:<\/p>\n\n<ul>\n  <li>using a <code class=\"language-plaintext highlighter-rouge\">case class<\/code> to save all the information of each friend<\/li>\n  <li>extract only the <code class=\"language-plaintext highlighter-rouge\">id<\/code> (as the author pretends)<\/li>\n<\/ul>\n\n<h4 id=\"using-case-classes\">Using case classes<\/h4>\n\n<p>Not very difficult, but remember that the <code class=\"language-plaintext highlighter-rouge\">Friends<\/code> json mapper definition needs to come before the <code class=\"language-plaintext highlighter-rouge\">Response<\/code> json mapper:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Friends<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">since<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span>\n<span class=\"k\">object<\/span> <span class=\"nc\">Friends<\/span> <span class=\"o\">{<\/span>\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">fmt<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">format<\/span><span class=\"o\">[<\/span><span class=\"kt\">Friends<\/span><span class=\"o\">]<\/span>\n<span class=\"o\">}<\/span>\n\n<span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Response<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">friend_ids<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">Friends<\/span><span class=\"o\">])<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">Response<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">userReads<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">Response<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n    <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"id\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"friends\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">Friends<\/span><span class=\"o\">]]<\/span>\n    <span class=\"o\">)<\/span> <span class=\"o\">(<\/span><span class=\"nv\">Response<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"extract-only-the-ids\">Extract only the ids<\/h4>\n\n<p>This solution was presented by <a href=\"http:\/\/stackoverflow.com\/a\/36215248\/4398050\">another user<\/a> and it\u2019s a little bit more elaborated:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Response<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">friend_ids<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">])<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">Response<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">userReads<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">Response<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n    <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"id\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"friends\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">]](<\/span><span class=\"nv\">Reads<\/span><span class=\"o\">.<\/span><span class=\"py\">seq<\/span><span class=\"o\">((<\/span><span class=\"nc\">__<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"id\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">]))<\/span>\n    <span class=\"o\">)(<\/span><span class=\"nv\">Response<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2 id=\"i-want-to-learn-more\">I want to learn more<\/h2>\n\n<p>If you are stuck with some error, check the source code at <a href=\"https:\/\/github.com\/pedrorijo91\/scala-play-json-examples\">GitHub<\/a>.<\/p>\n\n<p>If you want to read a little more about solutions from other authors, check these useful links:<\/p>\n\n<ul>\n  <li><a href=\"http:\/\/reactive.xploregroup.be\/blog\/13\/Play-JSON-in-Scala-intro-and-beyond-the-basics\">Reactive Xplore Group<\/a><\/li>\n  <li>Wojciech Programming Blog <a href=\"http:\/\/www.wlangiewicz.com\/2016\/03\/23\/json-in-play-framework-techniques-for-making-compatible-mappings\/\">Part 1<\/a> and <a href=\"http:\/\/www.wlangiewicz.com\/2016\/03\/25\/json-play-framework-advanced-libraries\/\">Part 2<\/a><\/li>\n  <li><a href=\"https:\/\/www.reddit.com\/r\/scala\/comments\/4bz89a\/how_to_correctly_parse_json_to_scala_case_class\/\">Scala reddit<\/a> where I got some of the knowledge<\/li>\n<\/ul>\n","pubDate":"Sat, 26 Mar 2016 19:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-json-part2\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-json-part2\/"},{"title":"Git Status Notifier","description":"<p><span class=\"dropcap\">G<\/span>it has become one of the most essential tools for every developer. While most developers trust in <a href=\"https:\/\/github.com\">GitHub<\/a> to host their git repositories, <a href=\"https:\/\/bitbucket.org\/\">Bitbucket<\/a>, and more recently <a href=\"https:\/\/gitlab.com\/\">Gitlab<\/a>, have become worthy alternatives.<\/p>\n\n<p>When users rely so much on those services for the everyday workflow, it became crucial for both, the providers and the users, to have almost non existing downtimes. One common approach to provide information to users about technical issues was to offer a status service (and API) for consulting the service status, similar to many other web services:<\/p>\n\n<ul>\n  <li><a href=\"https:\/\/status.github.com\/\">GitHub status<\/a><\/li>\n  <li><a href=\"http:\/\/status.bitbucket.org\/\">Bitbucket status<\/a><\/li>\n  <li><a href=\"https:\/\/status.gitlab.com\/\">Gitlab status<\/a><\/li>\n<\/ul>\n\n<h3 id=\"ddos\">DDOS<\/h3>\n\n<p>It is still fresh in memory the <a href=\"http:\/\/thehackernews.com\/2015\/03\/github-hit-by-massive-ddos-attack-from_27.html\">huge attack against GitHub<\/a>, just 1 year ago. Although rare, those kind of attacks can harm many developers who see themselves in trouble to proceed with their regular workflow (even if Git is a distributed system, it is still a problem when the Git server is down). Besides those big and somehow rare attacks, minor issues happen that may cause some itches. Now, if you work at a company like <a href=\"https:\/\/travis-ci.org\/\">Travis<\/a>, or <a href=\"https:\/\/www.codacy.com\/\">Codacy<\/a>, who depend heavily on git and the corresponding servers 24\/7, every itch may become a bit more problematic.<\/p>\n\n<h3 id=\"how-to-detect\">How to detect<\/h3>\n\n<p>Currently, I find that there\u2019s a problem on GitHub\/Bitbucket when I try to do push or pull on git and it takes too much time (and probably failing). Or I just saw a post on <a href=\"https:\/\/news.ycombinator.com\/\">Hacker News<\/a> where someone is complaining about a problem a couple of hours ago. But I want to know as soon as those services have any minor problem. So I built a small monitor: <a href=\"https:\/\/github.com\/pedrorijo91\/git-status-notifier\">Git Status Notifier<\/a>.<\/p>\n\n<h3 id=\"git-status-monitor\">Git Status Monitor<\/h3>\n\n<p>Git Status Notifier is a small and extensible monitor for GitHub and Bitbucket services (thinking about monitor Gitlab soon also) that alerts through Slack, Hipchat, or Email (using <a href=\"https:\/\/sendgrid.com\/\">Sengrid<\/a>) - and still thinking about using <a href=\"https:\/\/www.twilio.com\/\">Twillio<\/a> for SMS notifications.<\/p>\n\n<p>It is built using one Akka actor for each provider (one for GitHub and one for Bitbucket, if enabled). Each actor makes a request to the API and compares with the previous one. If there\u2019s any change, it will notify, using the configured channels.<\/p>\n\n<h4 id=\"how-to-run\">How to run<\/h4>\n\n<p>It is pretty simple to run it. All configurations are defined in the configuration file:<\/p>\n\n<ul>\n  <li>providers monitored<\/li>\n  <li>request timeout<\/li>\n  <li>time between checks<\/li>\n  <li>date time format (message display)<\/li>\n<\/ul>\n\n<p>Each notification channel must also be enabled (by default every channel is disabled).\nBesides that, each notification channel requires some settings, like the token, the room, etc.<\/p>\n\n<p>Feel free to check the project on <a href=\"https:\/\/github.com\/pedrorijo91\/git-status-notifier\">GitHub<\/a> to get more details.<\/p>\n","pubDate":"Tue, 08 Mar 2016 21:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/git-status-notifier\/","guid":"https:\/\/pedrorijo.com\/blog\/git-status-notifier\/"},{"title":"Saving JSON responses to your model in Scala","description":"<p><span class=\"dropcap\">I<\/span>f you deal with external APIs (like Twitter, Facebook, Intercom, Github, and many others) on a regular basis there\u2019s a big chance that you have already dealt with <a href=\"http:\/\/www.json.org\/\">JSON<\/a> answers before.<\/p>\n\n<p><em>JSON<\/em> (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages.<\/p>\n\n<p>JSON is built on two structures:<\/p>\n\n<ul>\n  <li>A collection of name\/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.<\/li>\n  <li>An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.<\/li>\n<\/ul>\n\n<p>A JSON object can be as simple as<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"key\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"value\"<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>containing just a simple key and value pair - in the limit, it could also be an empty set of key-values pair - or as complex as one wishes it:<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"widget\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n    <\/span><span class=\"nl\">\"debug\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"on\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n    <\/span><span class=\"nl\">\"window\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"title\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Sample Konfabulator Widget\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"name\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"main_window\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"width\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">500<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"height\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">500<\/span><span class=\"w\">\n    <\/span><span class=\"p\">},<\/span><span class=\"w\">\n    <\/span><span class=\"nl\">\"image\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"src\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Images\/Sun.png\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"name\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"sun1\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"hOffset\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">250<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"vOffset\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">250<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"alignment\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"center\"<\/span><span class=\"w\">\n    <\/span><span class=\"p\">},<\/span><span class=\"w\">\n    <\/span><span class=\"nl\">\"text\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"data\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Click Here\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"size\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">36<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"style\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"bold\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"name\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"text1\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"hOffset\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">250<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"vOffset\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">100<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"alignment\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"center\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n      <\/span><span class=\"nl\">\"onMouseUp\"<\/span><span class=\"w\"> <\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"sun1.opacity = (sun1.opacity \/ 100) * 90;\"<\/span><span class=\"w\">\n    <\/span><span class=\"p\">}<\/span><span class=\"w\">\n  <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>There are <a href=\"http:\/\/json.org\/example.html\">many other examples available<\/a>.<\/p>\n\n<h2 id=\"scala-and-json\">Scala and JSON<\/h2>\n\n<p>In most cases you will want to access and save information contained on the JSON document. <a href=\"https:\/\/www.playframework.com\/\">Play<\/a> provides a very complete library for dealing with JSON objects, <a href=\"https:\/\/www.playframework.com\/documentation\/2.4.x\/ScalaJson\">Play JSON<\/a>.<\/p>\n\n<blockquote>\n  <p>Note: If you are not including Play on your dependencies you can just include Play Json with<\/p>\n<\/blockquote>\n\n<blockquote>\n  <p><code class=\"language-plaintext highlighter-rouge\">libraryDependencies += \"com.typesafe.play\" % \"play-json_2.11\" % \"2.4.6\"<\/code><\/p>\n<\/blockquote>\n\n<p>For this example we will use <a href=\"https:\/\/developer.github.com\/v3\/\">GitHub API<\/a>. If you access <a href=\"https:\/\/api.github.com\/users\/pedrorijo91\">my user endpoint<\/a> you will get information about my user, in JSON. You should get something like:<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"login\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"pedrorijo91\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"id\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">1999050<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"avatar_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/avatars.githubusercontent.com\/u\/1999050?v=3\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"gravatar_id\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"html_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/github.com\/pedrorijo91\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"followers_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/followers\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"following_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/following{\/other_user}\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"gists_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/gists{\/gist_id}\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"starred_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/starred{\/owner}{\/repo}\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"subscriptions_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/subscriptions\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"organizations_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/orgs\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"repos_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/repos\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"events_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/events{\/privacy}\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"received_events_url\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"https:\/\/api.github.com\/users\/pedrorijo91\/received_events\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"User\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"site_admin\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">false<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"name\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Pedro Rijo\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"company\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Codacy\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"blog\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"http:\/\/pedrorijo.com\/\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"location\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"Lisbon, Portugal\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"email\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">null<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"hireable\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"bio\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">null<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"public_repos\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">35<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"public_gists\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"followers\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">23<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"following\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">62<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"created_at\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"2012-07-18T14:34:35Z\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"updated_at\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"2016-01-05T00:02:37Z\"<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>Now let\u2019s parse it. Suppose this answer is saved in a value named <code class=\"language-plaintext highlighter-rouge\">jsonString<\/code>, then all you need to do is:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">import<\/span> <span class=\"nn\">play.api.libs.json.Json<\/span>\n<span class=\"k\">val<\/span> <span class=\"nv\">jsonObject<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">parse<\/span><span class=\"o\">(<\/span><span class=\"n\">jsonString<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>and you will get the JSON object, ready to be easily queried. The easiest way to access fields is using the <code class=\"language-plaintext highlighter-rouge\">'\\'<\/code> operator.\nFor instance, to get the <code class=\"language-plaintext highlighter-rouge\">login<\/code> field you just need to write:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val<\/span> <span class=\"nv\">login<\/span> <span class=\"k\">=<\/span> <span class=\"n\">jsonObject<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"login\"<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>and you will get a <code class=\"language-plaintext highlighter-rouge\">JsValue<\/code> with the value <code class=\"language-plaintext highlighter-rouge\">pedrorijo91<\/code>. You can now convert this to a <code class=\"language-plaintext highlighter-rouge\">String<\/code>, or any other type, using:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">login<\/span><span class=\"o\">.<\/span><span class=\"py\">as<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<blockquote>\n  <p>Note: when testing, it may be useful to experiment on the sbt console, and when saving the JSON strings in a value, the <a href=\"http:\/\/www.scala-lang.org\/old\/node\/5514\">triple quote<\/a> may be handy<\/p>\n<\/blockquote>\n\n<h2 id=\"saving-json-documents-to-model-objects\">Saving JSON documents to model objects<\/h2>\n\n<p>That was the first part. What about saving the information? You probably want to map it to domain objects. The easiest way is to use <code class=\"language-plaintext highlighter-rouge\">case classes<\/code>.<\/p>\n\n<p>Imagine that some API returned the following answer:<\/p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"username\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"pedrorijo91\"<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"friends\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">100<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"enemies\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"mi\">10<\/span><span class=\"p\">,<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"isAlive\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"true\"<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>and you have the following model:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">isAlive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>To easily convert your JSON object to an <code class=\"language-plaintext highlighter-rouge\">User<\/code>, add the companion object with an implicit formatter:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">isAlive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span><span class=\"o\">)<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">User<\/span> <span class=\"o\">{<\/span>\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">userJsonFormat<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">format<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now, if you simply do:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val<\/span> <span class=\"nv\">jsonString<\/span> <span class=\"k\">=<\/span> <span class=\"s\">\"\"\" {\"username\":\"pedrorijo91\",\"friends\":100,\"enemies\":10,\"isAlive\":\"true\"} \"\"\"<\/span>\n<span class=\"k\">val<\/span> <span class=\"nv\">jsonObject<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">Json<\/span><span class=\"o\">.<\/span><span class=\"py\">parse<\/span><span class=\"o\">(<\/span><span class=\"n\">jsonString<\/span><span class=\"o\">)<\/span>\n<span class=\"nv\">jsonObject<\/span><span class=\"o\">.<\/span><span class=\"py\">as<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>You will get an <code class=\"language-plaintext highlighter-rouge\">User<\/code> with the expected fields defined. You can get to know more on the <a href=\"https:\/\/www.playframework.com\/documentation\/2.4.x\/ScalaJson#JsValue-to-a-model\">official documentation<\/a><\/p>\n\n<blockquote>\n  <p>Note, actually you just need <code class=\"language-plaintext highlighter-rouge\">Json.reads[User]<\/code> on the companion object. The <code class=\"language-plaintext highlighter-rouge\">format<\/code> allows you to also write a model as JSON directly.<\/p>\n<\/blockquote>\n\n<h2 id=\"life-aint-perfect\">Life ain\u2019t perfect<\/h2>\n\n<p>Unfortunately, some APIs we deal with, are not as nice. Suppose that instead of a <code class=\"language-plaintext highlighter-rouge\">isAlive<\/code> field, the JSON had an <code class=\"language-plaintext highlighter-rouge\">is_alive<\/code> field. Then the mapping between JSON and our model wouldn\u2019t be direct as before.<\/p>\n\n<p>There are two alternatives:<\/p>\n\n<ol>\n  <li>\n    <p>Adapt the case class<\/p>\n\n    <p>Instead of a a <code class=\"language-plaintext highlighter-rouge\">isAlive<\/code> we can name the class field <code class=\"language-plaintext highlighter-rouge\">is_alive<\/code><\/p>\n\n    <div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">is_alive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div>    <\/div>\n\n    <p>This creates an awful field accessor (<code class=\"language-plaintext highlighter-rouge\">is_alive<\/code>). One solution may be to hide that accessor, creating a wrapper. Add the <code class=\"language-plaintext highlighter-rouge\">private<\/code> qualifier and create a wrapper method:<\/p>\n\n    <div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"k\">private<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">is_alive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">isAlive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span> <span class=\"o\">=<\/span> <span class=\"n\">is_alive<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div>    <\/div>\n  <\/li>\n  <li>\n    <p>Create a custom Reads on the companion object<\/p>\n\n    <div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">isAlive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Boolean<\/span><span class=\"o\">)<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">User<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">import<\/span> <span class=\"nn\">play.api.libs.functional.syntax._<\/span>\n  <span class=\"k\">import<\/span> <span class=\"nn\">play.api.libs.json._<\/span>\n\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">userReads<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"username\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"friends\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"enemies\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"is_alive\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Boolean<\/span><span class=\"o\">]<\/span>\n    <span class=\"o\">)<\/span> <span class=\"o\">(<\/span><span class=\"nv\">User<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div>    <\/div>\n\n    <p>This custom Reads maps each JSON field to the case class constructor, allowing you to keep a nice case class, while creating instances directly from JSON objects.<\/p>\n  <\/li>\n<\/ol>\n\n<p>Yet another problem, what about APIs returning JSON with optional fields? What if the <code class=\"language-plaintext highlighter-rouge\">isAlive<\/code> field is not always present? Then the solution would be to use <code class=\"language-plaintext highlighter-rouge\">readNullable<\/code> and make the field optional:<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">username<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">friends<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">enemies<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Int<\/span><span class=\"o\">,<\/span> <span class=\"n\">isAlive<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Option<\/span><span class=\"o\">[<\/span><span class=\"kt\">Boolean<\/span><span class=\"o\">])<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">User<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">import<\/span> <span class=\"nn\">play.api.libs.functional.syntax._<\/span>\n  <span class=\"k\">import<\/span> <span class=\"nn\">play.api.libs.json._<\/span>\n\n  <span class=\"k\">implicit<\/span> <span class=\"k\">val<\/span> <span class=\"nv\">userReads<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Reads<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">(<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"username\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"friends\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"enemies\"<\/span><span class=\"o\">).<\/span><span class=\"py\">read<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"nf\">and<\/span>\n      <span class=\"o\">(<\/span><span class=\"nc\">JsPath<\/span> <span class=\"o\">\\<\/span> <span class=\"s\">\"is_alive\"<\/span><span class=\"o\">).<\/span><span class=\"py\">readNullable<\/span><span class=\"o\">[<\/span><span class=\"kt\">Boolean<\/span><span class=\"o\">]<\/span>\n    <span class=\"o\">)<\/span> <span class=\"o\">(<\/span><span class=\"nv\">User<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span> <span class=\"k\">_<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now you can map JSON answers to your model and deal with that information with all the benefits Scala provides.<\/p>\n\n<p>What about you? Do you have any other technique for dealing with JSON in Scala?<\/p>\n\n<h2 id=\"follow-up\">Follow up<\/h2>\n\n<p>If you want to see more advanced features, check out the follow up on <a href=\"https:\/\/pedrorijo.com\/blog\/scala-json-part2\">Saving JSON to Scala model - Part 2<\/a><\/p>\n\n<p>Also, checkout the source code at <a href=\"https:\/\/github.com\/pedrorijo91\/scala-play-json-examples\">GitHub<\/a> if you have any doubt.<\/p>\n","pubDate":"Tue, 05 Jan 2016 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/scala-json\/","guid":"https:\/\/pedrorijo.com\/blog\/scala-json\/"},{"title":"Open Source Development: a few guidelines","description":"<p>This post was originally published on <a href=\"http:\/\/blog.codacy.com\/2015\/12\/17\/open-source-development-a-few-guidelines\/\">Codacy blog by me<\/a>:<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/codacy-logo-name.png\" alt=\"Codacy\" title=\"Codacy\" width=\"300px\" \/><\/p>\n\n<p>I believe the Open Source movement is the biggest breakthrough in software development. Open Source has allowed many projects to increase the number of contributors (and contributions) to unreachable standards for any enterprise. Just take a look at the <a href=\"https:\/\/github.com\/torvalds\/linux\">Linux kernel<\/a>, which counts with 500,000+ commits and 5,600+ contributors.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/linuxGH.png\" alt=\"Linux kernel, an open source example\" title=\"Linux kernel, an open source example\" width=\"700px\" \/><\/p>\n\n<p>In this evolution, platforms such as <a href=\"https:\/\/sourceforge.net\/\">SourceForge<\/a>, <a href=\"https:\/\/code.google.com\/\">Google Code<\/a>, <a href=\"https:\/\/bitbucket.org\/\">Bitbucket<\/a>, and especially <a href=\"https:\/\/github.com\/\">GitHub<\/a> played a fundamental role connecting developers all around the world and wide-spreading remote contributions.<\/p>\n\n<p>Personally, I had the opportunity of working on Open Source projects while working at <a href=\"http:\/\/fenixedu.github.io\/\">FenixEdu<\/a>. At Codacy, we also have <a href=\"https:\/\/github.com\/codacy\">several open source<\/a> projects. We have some docker engines to support our code analysis, we have some code coverage tools that help users to import coverage reports to Codacy, and we also have projects like our Scala clients for <a href=\"https:\/\/github.com\/codacy\/bitbucket-scala-client\">Bitbucket API<\/a> and <a href=\"https:\/\/github.com\/codacy\/stash-scala-client\">Stash API<\/a>. While the last two should be far more interesting to the general community, having all of them open source allows users to report problems and get fixes way faster. It\u2019s not uncommon to have  users contributing to improve our tools. A good example is our <a href=\"https:\/\/github.com\/codacy\/python-codacy-coverage\/pulls?q=is%3Apr+is%3Aclosed\">python-codacy-coverage<\/a> project which has received valuable help from the community.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/gh-world.png\" alt=\"\" title=\"\" width=\"400px\" \/><\/p>\n\n<p>Lately we have also been devoting more time to our open source projects. We have been busy on providing proper documentation and taking a careful look for created issues and pending pull requests.<\/p>\n\n<p>In this process we realized that it is very common to have users who want to contribute to the Open Source movement but don\u2019t really know how to start, so we decided to collect some good practices for all of those who want to contribute to the Open Source movement and simply don\u2019t know how to.<\/p>\n\n<h3 id=\"if-you-are-an-open-source-project-owner\">If you are an open source project owner:<\/h3>\n\n<ul>\n  <li><strong><u>Create a README file<\/u><\/strong>, providing an overview about the project as well as some usage instructions. This may include some <a href=\"\/assets\/img\/node-badges.png\">project badges<\/a> (look at our <a href=\"https:\/\/github.com\/codacy\/node-codacy-coverage\">node-codacy-coverage<\/a> project as an example) that visually indicate several stats. I usually include the build status, current release version, coverage, and Codacy project grade. It is also a common practice to include a <em>Troubleshooting<\/em> section, for common errors and how to solve them.<\/li>\n  <li><strong><u>Create a CONTRIBUTING file<\/u><\/strong>, providing instructions on how to contribute to the project. Take a look at <a href=\"https:\/\/github.com\/codacy\/bitbucket-scala-client\/blob\/master\/CONTRIBUTING.md\">this Codacy project<\/a>, for instance.<\/li>\n  <li><strong><u>Automate tasks.<\/u><\/strong> A new contributor may not be fully into the project. By providing a simple mechanism to compile, run, and test, he will be much more efficient. An easy way to quickly provide a fully configured environment may be to use <a href=\"https:\/\/www.docker.com\/\">dockers<\/a>.<\/li>\n  <li><strong><u>Integrate with a Continuous Integration (CI) platform.<\/u><\/strong> The CI helps you by assuring the contributions don\u2019t break your project. CI should be built upon tests - a piece of code all managers like to postpone when the sprint gets short - that can be run to ensure no previous code has been broken by recent changes. There are plenty of CI platforms available. Among the most used ones we have <a href=\"https:\/\/circleci.com\/\">CircleCI<\/a>, <a href=\"https:\/\/travis-ci.org\/\">Travis<\/a>, <a href=\"https:\/\/www.atlassian.com\/software\/bamboo\/\">Bamboo<\/a>, <a href=\"https:\/\/codeship.com\/\">CodeShip<\/a>, and <a href=\"https:\/\/jenkins-ci.org\/\">Jenkins<\/a>.<\/li>\n  <li><strong><u>Define coding standards<\/u><\/strong>, usually followed by format settings for the most common IDE(s). At Codacy we have our own IntelliJ settings so we can reduce visual pollution on commits diffs. Codacy can be used to automatically review code, and integrated in development workflows, so you don\u2019t waste time enforcing coding standards.<\/li>\n  <li><strong><u>Create issues for known\/reported problems.<\/u><\/strong> This allows contributors to be aware of contributing opportunities. Also, make an effort to keep issues updated, i.e., answer existing comments, close solved issues, correctly label them, and so on. Labels can help you say which problems won\u2019t be solved, which you need some help with, which ones are bugs, performance, improvements, etc.<\/li>\n  <li><strong><u>Watch incoming pull requests.<\/u><\/strong> Contributions will appear in the form of pull requests. Don\u2019t let a pull request remain ignored for weeks without a single word to the author.<\/li>\n  <li><strong><u>Tag your releases appropriately.<\/u><\/strong> This way users can inspect the code at the state of each release, allowing them to debug some eventual problem. GitHub provides <a href=\"https:\/\/help.github.com\/articles\/creating-releases\/\">documentation on tags<\/a> which may be useful. Also, <a href=\"http:\/\/semver.org\/\">semantic versioning<\/a> is the current standard to project versioning. Among other properties, users are immediately aware what kind of changes the new version introduces. There is also this great post on <a href=\"https:\/\/blog.gopheracademy.com\/advent-2015\/semver\/\">working with semantic versions<\/a>, check it out to better understand the topic.<\/li>\n  <li><strong><u>Choose a license.<\/u><\/strong> It is very common not to have a license in your Open Source. Mostly because no one really understands licenses. <a href=\"http:\/\/choosealicense.com\/\">Choose a license<\/a> demystifies all these ghosts. If you don\u2019t care about it, use the <a href=\"http:\/\/choosealicense.com\/licenses\/mit\/\">MIT License<\/a>, which is one of the most permissive ones out there. If you really want to check the differences between existing license, <a href=\"http:\/\/choosealicense.com\/licenses\/\">check this list<\/a>.<\/li>\n  <li><strong><u>Ask for help<\/u><\/strong> if you can\u2019t manage all the work of maintaining the project. There are always users available to help maintaining a project. Discuss the idea\/vision of your project so you both get aligned before starting to work together.<\/li>\n<\/ul>\n\n<h3 id=\"if-you-want-to-contribute-to-an-open-source-project\">If you want to contribute to an open source project:<\/h3>\n\n<p>It should be pretty easy if the project owners have followed the previous guidelines.<\/p>\n\n<ul>\n  <li><strong><u>Read all the documentation<\/u><\/strong> they made an effort to create (<em>README<\/em>, and specially <em>CONTRIBUTING<\/em>, if present). The documentation should provide enough info for you to start.<\/li>\n  <li><strong><u>Fork<\/u><\/strong> the project<\/li>\n  <li><strong><u>Announce you are on a issue.<\/u><\/strong> If you are trying to solve a reported issue, comment that you intend to solve it, and possibly discuss with the project maintainers the best approach <strong>before starting to code<\/strong><\/li>\n  <li><strong><u>Create a new branch<\/u><\/strong> on your fork and code your solution (it\u2019s always good to add\/fix tests)<\/li>\n  <li><strong><u>Open a pull request<\/u><\/strong> after having pushed your changes.<\/li>\n  <li><strong><u>Iterate your changes<\/u><\/strong> as the project maintainers comment your code<\/li>\n  <li>Your pull request should be accepted as you converge to an accepted solution<\/li>\n<\/ul>\n\n<p>If there is no documentation about how to contribute, try to make the most clean and understandable code so reviewers can have their work eased. Put yourself in a reviewer situation. Would you like to review your own code?  Would you like to have that code in your project? If you can\u2019t find a nice solution, remind that the community is always there to help.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/calvin-arguing.jpeg\" alt=\"\" title=\"\" width=\"400px\" \/><\/p>\n\n<p>There are also some discussions about what are the best practices to contribute through pull requests. While some may argue that a pull request should contain a single commit, gathering all changes and making sure that every commit is in a deployable state, others defend that a pull request may be logical split into several smaller chunks (commits) , making it easier to review the pull request. Check some discussions <a href=\"http:\/\/ndlib.github.io\/practices\/one-commit-per-pull-request\/#git-rebase-interactive\">here<\/a>, <a href=\"http:\/\/codeinthehole.com\/writing\/pull-requests-and-other-good-practices-for-teams-using-github\/\">here<\/a>, or even in <a href=\"https:\/\/www.reddit.com\/r\/git\/comments\/343jld\/do_you_prefer_pull_requests_that_contain_one\/\">reddit<\/a> about pull requests best practices.<\/p>\n\n<p>That is all you should need if you want to start contributing to Open Source projects.<\/p>\n\n<h3 id=\"first-timers\">First timers<\/h3>\n\n<p>Still on Open Source contributions, Kent C. Dodds (maintainer of <a href=\"https:\/\/github.com\/formly-js\/angular-formly\">angular-formly<\/a>), wrote a very <a href=\"https:\/\/medium.com\/@kentcdodds\/first-timers-only-78281ea47455#.3ghth459p\">interesting article<\/a>, where besides some good practices, Kent introduces a awesome new  initiative: <strong>contributions to first timers only<\/strong>.<\/p>\n\n<p>First timers are developers who never had the change to contribute to a Open Source project, developers who want to make their first ever contribution.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/dark-side.jpg\" alt=\"\" title=\"\" width=\"200px\" \/><\/p>\n\n<p>This initiative creates a soft entry to Open Source for those who have been looking for the opportunity but may have been frighten by the process. This also increases the number of open source contributors in the community, making every project to benefit from it in the long term. That is why more projects should think about  creating opportunities to first timers.<\/p>\n\n<p>If you are looking into your first Open Source contribution just <a href=\"https:\/\/github.com\/search?utf8=%E2%9C%93&amp;q=label%3Afirst-timers-only+is%3Aopen&amp;type=Issues&amp;ref=searchresults\">search for it in GitHub<\/a>.<\/p>\n\n<p>And keep in mind, if you want to improve your code quality, Codacy is fully integrated with GitHub and Bitbucket, and it is <a href=\"https:\/\/www.codacy.com\/pricing\">free to Open Source<\/a><\/p>\n","pubDate":"Fri, 18 Dec 2015 00:10:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/open-source-guidelines\/","guid":"https:\/\/pedrorijo.com\/blog\/open-source-guidelines\/"},{"title":"Play framework, Slick and MySQL Tutorial","description":"<blockquote>\n  <p>Edit: You may want to have a look at the updated example using Play 2.7 instead of Play 2.4 at <a href=\"https:\/\/pedrorijo.com\/blog\/play-slick-updated\">Play Framework and Slick example updated<\/a><\/p>\n<\/blockquote>\n\n<p><span class=\"dropcap\">T<\/span>ypical nowadays applications need to store some persistent data frequently. And when we talk about persistent storage we are talking about databases. Among the most common applications, we have web applications. And it is uncommon to have a web application that does not require persistent storage.<\/p>\n\n<p>Building webapps in Scala is typically done using the <a href=\"https:\/\/www.playframework.com\/\">Play framework<\/a>. And for persistent storage, Scala developers typically appeal to <a href=\"http:\/\/slick.typesafe.com\/\">Slick<\/a>. Even though it is possible to use Java libraries and frameworks like the well-know <a href=\"http:\/\/hibernate.org\/\">Hibernate<\/a> - described as an <em>high-performance Object\/Relational persistence and query service<\/em> - Slick has a Scala-like API, where everything is pretty similar to Scala collections, making Slick way more attractive to Scala developers.<\/p>\n\n<p>Another difference that should be kept in mind, is that Slick is not an ORM like Hibernate. Slick is more like a functional-relational mapper. And a more detailed difference between Slick and ORMs is available in the <a href=\"http:\/\/slick.typesafe.com\/doc\/2.1.0\/orm-to-slick.html\">Slick documentation<\/a>. Slick also allows the use of multiple backends, meaning that you can use a lot of different databases with slick (H2, MySQL, PostgreSQL, and <a href=\"http:\/\/slick.typesafe.com\/doc\/3.1.0\/supported-databases.html\">many others<\/a>).<\/p>\n\n<p>As stated in Slick docs:<\/p>\n\n<blockquote>\n  <p>Slick is a modern database query and access library for Scala. It allows you to work with stored data almost as if you were using Scala collections (\u2026). You can write your database queries in Scala instead of SQL, thus profiting from the static checking, compile-time safety and compositionality of Scala.<\/p>\n<\/blockquote>\n\n<h2 id=\"webapps-with-persistent-storage\">Webapps with persistent storage<\/h2>\n\n<p>When building a webapp in Scala with persistent storage you will probably think about using Play and Slick together.\nTo achieve that you probably want to use <a href=\"https:\/\/github.com\/playframework\/play-slick\">Play Slick<\/a>, a Play module that makes Slick a first-class citizen of Play. It consists of two features:<\/p>\n\n<ul>\n  <li>Integration of Slick into Play\u2019s application lifecycle.<\/li>\n  <li>Support for Play database evolutions.<\/li>\n<\/ul>\n\n<p>This module tries to provide an easy way to integrate Play and Slick, but while I was looking for some minimal example I noticed that there was missing some updated example which used <code class=\"language-plaintext highlighter-rouge\">Play 2.4<\/code> and <code class=\"language-plaintext highlighter-rouge\">Slick 3.1.0<\/code>.\nHere are the closest examples I\u2019ve found:<\/p>\n\n<ul>\n  <li><a href=\"https:\/\/github.com\/playframework\/play-slick\/tree\/master\/samples\">Play Slick samples<\/a>, that are pretty hard to reuse due to the <a href=\"https:\/\/github.com\/playframework\/play-slick\/issues\/278#issuecomment-144388541\">complex sbt setup<\/a><\/li>\n  <li>An example which combines Play 2.4 and Slick 3, but that uses <a href=\"http:\/\/brettwooldridge.github.io\/HikariCP\/\">HikariCP<\/a>, and without the use of the Play Slick module, at <a href=\"https:\/\/github.com\/wsargent\/play-slick-3.0\/\">https:\/\/github.com\/wsargent\/play-slick-3.0\/<\/a><\/li>\n  <li>And finally, a really nice <a href=\"http:\/\/playhorizon.blogspot.in\/p\/play-scala-tutorials_23.html\">tutorial<\/a> and <a href=\"https:\/\/github.com\/bhavyalatha26\/play-scala-slick-example\">code<\/a>, that unfortunately has a lot of useless code for those who just want to use Play and Slick. Between other issues, it provides string internationalization, uses dependency injection with <a href=\"https:\/\/github.com\/google\/guice\">guice<\/a>, abuses in the use of <code class=\"language-plaintext highlighter-rouge\">Traits<\/code> and implementing classes, and so on. All those features just make the example less clean.<\/li>\n<\/ul>\n\n<p>That said, I decided to compile the available examples and tutorials in the most simple and comprehensive example I could, mostly based on the <a href=\"http:\/\/playhorizon.blogspot.in\/p\/play-scala-tutorials_23.html\">last example<\/a>.\nThis example uses MySQL database, but it should be straightforward to implement it using other database.<\/p>\n\n<h2 id=\"creating-a-play-app-with-slick-from-scratch\">Creating a Play app with Slick from scratch<\/h2>\n\n<p>First, there are some required software you need to have available at your machine:<\/p>\n\n<ol>\n  <li>Scala<\/li>\n  <li><a href=\"http:\/\/www.scala-sbt.org\/\">sbt<\/a><\/li>\n  <li><a href=\"https:\/\/www.typesafe.com\/community\/core-tools\/activator-and-sbt\">Activator<\/a> (not essential, but nice for getting a Play app template)<\/li>\n  <li><a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, as we have chosen MySQL as the database<\/li>\n<\/ol>\n\n<p>After installing everything you need, make sure you have MySQL server running, and a database named <code class=\"language-plaintext highlighter-rouge\">playScalaSlickExample<\/code> (you may chose another name, it will be described how to change later).<\/p>\n\n<h3 id=\"making-the-webapp\">Making the webapp<\/h3>\n\n<p>Now it\u2019s time to start creating our app. The simplest way to do it is to run:<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>activator new application-name play-scala\n<\/code><\/pre><\/div><\/div>\n\n<p>specifying your application name by replacing <em>application-name<\/em> by the desired name.\nIf you opted by not installing activator you can create a sbt project manually, adding the dependencies and the <a href=\"https:\/\/www.playframework.com\/documentation\/2.0\/Anatomy\">correct folder structure<\/a>.<\/p>\n\n<p>At this moment you should have your base template, something like <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/tree\/step1\">this<\/a><\/p>\n\n<p>The next step is to add all the logic and models without using a database. We\u2019ll make it using a variable representing the sequence of users (please, never use variables in Scala again). To do that, we\u2019ll need to:<\/p>\n\n<h4 id=\"1-create-the-model\">1. Create the model<\/h4>\n\n<p>Besides the User, we\u2019ll need a case class for the form submitted data (UserFormData), an object to deal with form submission (UserForm), and a object to answer queries (Users).<\/p>\n\n<p>Besides that, we\u2019ll create a service layer. This is not strictly necessary, but it\u2019s a good practice to have a service layer that\u2019s responsible to get and manipulate the information the controller needs. In our case it is so simple that we\u2019ll omit it, but you can check it on <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/blob\/master\/app\/services\/UserService.scala\">Github<\/a>.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">firstName<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">lastName<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">mobile<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">email<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span>\n\n<span class=\"k\">case<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">UserFormData<\/span><span class=\"o\">(<\/span><span class=\"n\">firstName<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">lastName<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">,<\/span> <span class=\"n\">mobile<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">email<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span><span class=\"o\">)<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">UserForm<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">val<\/span> <span class=\"nv\">form<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">Form<\/span><span class=\"o\">(<\/span>\n    <span class=\"nf\">mapping<\/span><span class=\"o\">(<\/span>\n      <span class=\"s\">\"firstName\"<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">nonEmptyText<\/span><span class=\"o\">,<\/span>\n      <span class=\"s\">\"lastName\"<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">nonEmptyText<\/span><span class=\"o\">,<\/span>\n      <span class=\"s\">\"mobile\"<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">longNumber<\/span><span class=\"o\">,<\/span>\n      <span class=\"s\">\"email\"<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">email<\/span>\n    <span class=\"o\">)(<\/span><span class=\"nv\">UserFormData<\/span><span class=\"o\">.<\/span><span class=\"py\">apply<\/span><span class=\"o\">)(<\/span><span class=\"nv\">UserFormData<\/span><span class=\"o\">.<\/span><span class=\"py\">unapply<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n\n<span class=\"k\">object<\/span> <span class=\"nc\">Users<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">var<\/span> <span class=\"n\">users<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">Seq<\/span><span class=\"o\">()<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">add<\/span><span class=\"o\">(<\/span><span class=\"n\">user<\/span><span class=\"k\">:<\/span> <span class=\"kt\">User<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">String<\/span> <span class=\"o\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"n\">users<\/span> <span class=\"k\">=<\/span> <span class=\"n\">users<\/span> <span class=\"o\">:+<\/span> <span class=\"nv\">user<\/span><span class=\"o\">.<\/span><span class=\"py\">copy<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">length<\/span><span class=\"o\">)<\/span> <span class=\"c1\">\/\/ manual id increment<\/span>\n    <span class=\"s\">\"User successfully added\"<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">delete<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Option<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"k\">val<\/span> <span class=\"nv\">originalSize<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">length<\/span>\n    <span class=\"n\">users<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">filterNot<\/span><span class=\"o\">(<\/span><span class=\"nv\">_<\/span><span class=\"o\">.<\/span><span class=\"py\">id<\/span> <span class=\"o\">==<\/span> <span class=\"n\">id<\/span><span class=\"o\">)<\/span>\n    <span class=\"nc\">Some<\/span><span class=\"o\">(<\/span><span class=\"n\">originalSize<\/span> <span class=\"o\">-<\/span> <span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">length<\/span><span class=\"o\">)<\/span> <span class=\"c1\">\/\/ returning the number of deleted users<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">get<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Option<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">find<\/span><span class=\"o\">(<\/span><span class=\"nv\">_<\/span><span class=\"o\">.<\/span><span class=\"py\">id<\/span> <span class=\"o\">==<\/span> <span class=\"n\">id<\/span><span class=\"o\">)<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">listAll<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"n\">users<\/span>\n\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"2-add-the-controllers\">2. Add the controllers<\/h4>\n\n<p>Now it\u2019s time to add the endpoints to which the application will respond.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">class<\/span> <span class=\"nc\">ApplicationController<\/span> <span class=\"k\">extends<\/span> <span class=\"nc\">Controller<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">index<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Action<\/span><span class=\"o\">[<\/span><span class=\"kt\">AnyContent<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">Action<\/span> <span class=\"o\">{<\/span> <span class=\"k\">implicit<\/span> <span class=\"n\">request<\/span> <span class=\"k\">=&gt;<\/span>\n    <span class=\"k\">val<\/span> <span class=\"nv\">users<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">UserService<\/span><span class=\"o\">.<\/span><span class=\"py\">listAllUsers<\/span>\n    <span class=\"nc\">Ok<\/span><span class=\"o\">(<\/span><span class=\"nv\">views<\/span><span class=\"o\">.<\/span><span class=\"py\">html<\/span><span class=\"o\">.<\/span><span class=\"py\">index<\/span><span class=\"o\">(<\/span><span class=\"nv\">UserForm<\/span><span class=\"o\">.<\/span><span class=\"py\">form<\/span><span class=\"o\">,<\/span> <span class=\"n\">users<\/span><span class=\"o\">))<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">addUser<\/span><span class=\"o\">()<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">Action<\/span> <span class=\"o\">{<\/span> <span class=\"k\">implicit<\/span> <span class=\"n\">request<\/span> <span class=\"k\">=&gt;<\/span>\n    <span class=\"nv\">UserForm<\/span><span class=\"o\">.<\/span><span class=\"py\">form<\/span><span class=\"o\">.<\/span><span class=\"py\">bindFromRequest<\/span><span class=\"o\">.<\/span><span class=\"py\">fold<\/span><span class=\"o\">(<\/span>\n      <span class=\"c1\">\/\/ if any error in submitted data<\/span>\n      <span class=\"n\">errorForm<\/span> <span class=\"k\">=&gt;<\/span> <span class=\"nc\">Ok<\/span><span class=\"o\">(<\/span><span class=\"nv\">views<\/span><span class=\"o\">.<\/span><span class=\"py\">html<\/span><span class=\"o\">.<\/span><span class=\"py\">index<\/span><span class=\"o\">(<\/span><span class=\"n\">errorForm<\/span><span class=\"o\">,<\/span> <span class=\"nv\">Seq<\/span><span class=\"o\">.<\/span><span class=\"py\">empty<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">])),<\/span>\n      <span class=\"n\">data<\/span> <span class=\"k\">=&gt;<\/span> <span class=\"o\">{<\/span>\n        <span class=\"k\">val<\/span> <span class=\"nv\">newUser<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">User<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,<\/span> <span class=\"nv\">data<\/span><span class=\"o\">.<\/span><span class=\"py\">firstName<\/span><span class=\"o\">,<\/span> <span class=\"nv\">data<\/span><span class=\"o\">.<\/span><span class=\"py\">lastName<\/span><span class=\"o\">,<\/span> <span class=\"nv\">data<\/span><span class=\"o\">.<\/span><span class=\"py\">mobile<\/span><span class=\"o\">,<\/span> <span class=\"nv\">data<\/span><span class=\"o\">.<\/span><span class=\"py\">email<\/span><span class=\"o\">)<\/span>\n        <span class=\"k\">val<\/span> <span class=\"nv\">res<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">UserService<\/span><span class=\"o\">.<\/span><span class=\"py\">addUser<\/span><span class=\"o\">(<\/span><span class=\"n\">newUser<\/span><span class=\"o\">)<\/span>\n        <span class=\"nc\">Redirect<\/span><span class=\"o\">(<\/span><span class=\"nv\">routes<\/span><span class=\"o\">.<\/span><span class=\"py\">ApplicationController<\/span><span class=\"o\">.<\/span><span class=\"py\">index<\/span><span class=\"o\">())<\/span>\n      <span class=\"o\">})<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">deleteUser<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">Action<\/span> <span class=\"o\">{<\/span> <span class=\"k\">implicit<\/span> <span class=\"n\">request<\/span> <span class=\"k\">=&gt;<\/span>\n    <span class=\"nv\">UserService<\/span><span class=\"o\">.<\/span><span class=\"py\">deleteUser<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"o\">)<\/span>\n    <span class=\"nc\">Redirect<\/span><span class=\"o\">(<\/span><span class=\"nv\">routes<\/span><span class=\"o\">.<\/span><span class=\"py\">ApplicationController<\/span><span class=\"o\">.<\/span><span class=\"py\">index<\/span><span class=\"o\">())<\/span>\n  <span class=\"o\">}<\/span>\n\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Besides the controller you\u2019ll also need to configure the <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/blob\/master\/conf\/routes\">routes file<\/a>:<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>GET     \/                           controllers.ApplicationController.index\nPOST    \/add                        controllers.ApplicationController.addUser\nGET     \/delete\/:id                 controllers.ApplicationController.deleteUser(id : Long)\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"3-and-dont-forget-about-the-views\">3. And don\u2019t forget about the views<\/h4>\n\n<p>Finally, we\u2019ll need to create the view to our application. The view will display a user creation form, and the existent users list.<\/p>\n\n<p>Once again, you can check it out on <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/tree\/step2\/app\/views\">Github<\/a>.<\/p>\n\n<p>At this moment you should have something similar to <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/tree\/step2\">this code<\/a><\/p>\n\n<h3 id=\"persisting-data\">Persisting data<\/h3>\n\n<p>This was the first part. Now it\u2019s time to configure the database for our application. Let\u2019s go through each step:<\/p>\n\n<h4 id=\"0-declare-dependencies\">0. Declare dependencies<\/h4>\n\n<p>Of course, first we\u2019ll need to declare some dependencies to use slick, play-slick, and mysql - the chosen database for us. Add these 3 dependencies to your <code class=\"language-plaintext highlighter-rouge\">build.sbt<\/code><\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code> \"mysql\" % \"mysql-connector-java\" % \"5.1.34\"\n \"com.typesafe.play\" %% \"play-slick\" % \"1.1.0\"\n \"com.typesafe.play\" %% \"play-slick-evolutions\" % \"1.1.0\"\n<\/code><\/pre><\/div><\/div>\n\n<p>Also, if you have a <code class=\"language-plaintext highlighter-rouge\">jdbc<\/code> dependency declared in your <code class=\"language-plaintext highlighter-rouge\">build.sbt<\/code> file, remove it, or it will cause some errors in the compilation.<\/p>\n\n<h4 id=\"1-add-configurations-to-confapplicationconf\">1. Add configurations to <code class=\"language-plaintext highlighter-rouge\">conf\/application.conf<\/code><\/h4>\n\n<p>We need to specify how will the play application connect to the database.\nThe following lines specify the database driver, in this case MySQL, the database and its user\/password. Whatever the name you choose to the database (if you prefer other name to <code class=\"language-plaintext highlighter-rouge\">playScalaSlickExample<\/code>), make sure it exists before starting the application.<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>slick.dbs.default.driver = \"slick.driver.MySQLDriver$\"\nslick.dbs.default.db.driver = \"com.mysql.jdbc.Driver\"\nslick.dbs.default.db.url = \"jdbc:mysql:\/\/localhost\/playScalaSlickExample\"\nslick.dbs.default.db.user = \"root\"\nslick.dbs.default.db.password = \"\"\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"2-integrate-our-models-with-slick\">2. Integrate our models with slick<\/h4>\n\n<p>Now it\u2019s time to convert our models to slick objects, i.e. provide information for slick to map between classes and tables.<\/p>\n\n<p>In our case, we want to map the <code class=\"language-plaintext highlighter-rouge\">User<\/code> class\/instances. Our case class will suffer no changes, but we need to create another class that tells slick how to map. I like to name those classes something like <code class=\"language-plaintext highlighter-rouge\">XTableDef<\/code>, where <code class=\"language-plaintext highlighter-rouge\">X<\/code> is the name of the model (case) class, but you can give them different names.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">class<\/span> <span class=\"nc\">UserTableDef<\/span><span class=\"o\">(<\/span><span class=\"n\">tag<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Tag<\/span><span class=\"o\">)<\/span> <span class=\"k\">extends<\/span> <span class=\"nc\">Table<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">](<\/span><span class=\"n\">tag<\/span><span class=\"o\">,<\/span> <span class=\"s\">\"user\"<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">id<\/span> <span class=\"k\">=<\/span> <span class=\"n\">column<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">](<\/span><span class=\"s\">\"id\"<\/span><span class=\"o\">,<\/span> <span class=\"nv\">O<\/span><span class=\"o\">.<\/span><span class=\"py\">PrimaryKey<\/span><span class=\"o\">,<\/span><span class=\"nv\">O<\/span><span class=\"o\">.<\/span><span class=\"py\">AutoInc<\/span><span class=\"o\">)<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">firstName<\/span> <span class=\"k\">=<\/span> <span class=\"n\">column<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">](<\/span><span class=\"s\">\"first_name\"<\/span><span class=\"o\">)<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">lastName<\/span> <span class=\"k\">=<\/span> <span class=\"n\">column<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">](<\/span><span class=\"s\">\"last_name\"<\/span><span class=\"o\">)<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">mobile<\/span> <span class=\"k\">=<\/span> <span class=\"n\">column<\/span><span class=\"o\">[<\/span><span class=\"kt\">Long<\/span><span class=\"o\">](<\/span><span class=\"s\">\"mobile\"<\/span><span class=\"o\">)<\/span>\n  <span class=\"k\">def<\/span> <span class=\"nf\">email<\/span> <span class=\"k\">=<\/span> <span class=\"n\">column<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">](<\/span><span class=\"s\">\"email\"<\/span><span class=\"o\">)<\/span>\n\n  <span class=\"k\">override<\/span> <span class=\"k\">def<\/span> <span class=\"nf\">*<\/span> <span class=\"k\">=<\/span>\n    <span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"o\">,<\/span> <span class=\"n\">firstName<\/span><span class=\"o\">,<\/span> <span class=\"n\">lastName<\/span><span class=\"o\">,<\/span> <span class=\"n\">mobile<\/span><span class=\"o\">,<\/span> <span class=\"n\">email<\/span><span class=\"o\">)<\/span> <span class=\"o\">&lt;&gt;(<\/span><span class=\"nv\">User<\/span><span class=\"o\">.<\/span><span class=\"py\">tupled<\/span><span class=\"o\">,<\/span> <span class=\"nv\">User<\/span><span class=\"o\">.<\/span><span class=\"py\">unapply<\/span><span class=\"o\">)<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Note that the <em>O.PrimaryKey<\/em> and <em>O.AutoInc<\/em> constants indicate Slick that the <em>id<\/em> column is the primary key, and it should be incremented by the database itself.<\/p>\n\n<p>Now we also need to adapt our <code class=\"language-plaintext highlighter-rouge\">Users<\/code> object, that was used to make the queries.<\/p>\n\n<p>To get the database object we can write<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val<\/span> <span class=\"nv\">dbConfig<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">DatabaseConfigProvider<\/span><span class=\"o\">.<\/span><span class=\"py\">get<\/span><span class=\"o\">[<\/span><span class=\"kt\">JdbcProfile<\/span><span class=\"o\">](<\/span><span class=\"nv\">Play<\/span><span class=\"o\">.<\/span><span class=\"py\">current<\/span><span class=\"o\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We\u2019ll also need to create a table query. This table query object will map to the table, meaning all queries are done through this object<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val<\/span> <span class=\"nv\">users<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">TableQuery<\/span><span class=\"o\">[<\/span><span class=\"kt\">UserTableDef<\/span><span class=\"o\">]<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now we\u2019ll rewrite the methods to use the database instead of the in-memory sequence holding all users. This will change the methods signature, leading to changes in the service and possibly controllers.<\/p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">object<\/span> <span class=\"nc\">Users<\/span> <span class=\"o\">{<\/span>\n\n  <span class=\"k\">val<\/span> <span class=\"nv\">dbConfig<\/span> <span class=\"k\">=<\/span> <span class=\"nv\">DatabaseConfigProvider<\/span><span class=\"o\">.<\/span><span class=\"py\">get<\/span><span class=\"o\">[<\/span><span class=\"kt\">JdbcProfile<\/span><span class=\"o\">](<\/span><span class=\"nv\">Play<\/span><span class=\"o\">.<\/span><span class=\"py\">current<\/span><span class=\"o\">)<\/span>\n\n  <span class=\"k\">val<\/span> <span class=\"nv\">users<\/span> <span class=\"k\">=<\/span> <span class=\"nc\">TableQuery<\/span><span class=\"o\">[<\/span><span class=\"kt\">UserTableDef<\/span><span class=\"o\">]<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">add<\/span><span class=\"o\">(<\/span><span class=\"n\">user<\/span><span class=\"k\">:<\/span> <span class=\"kt\">User<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Future<\/span><span class=\"o\">[<\/span><span class=\"kt\">String<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nv\">dbConfig<\/span><span class=\"o\">.<\/span><span class=\"py\">db<\/span><span class=\"o\">.<\/span><span class=\"py\">run<\/span><span class=\"o\">(<\/span><span class=\"n\">users<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">user<\/span><span class=\"o\">).<\/span><span class=\"py\">map<\/span><span class=\"o\">(<\/span><span class=\"n\">res<\/span> <span class=\"k\">=&gt;<\/span> <span class=\"s\">\"User successfully added\"<\/span><span class=\"o\">).<\/span><span class=\"py\">recover<\/span> <span class=\"o\">{<\/span>\n      <span class=\"k\">case<\/span> <span class=\"n\">ex<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Exception<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nv\">ex<\/span><span class=\"o\">.<\/span><span class=\"py\">getCause<\/span><span class=\"o\">.<\/span><span class=\"py\">getMessage<\/span>\n    <span class=\"o\">}<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">delete<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Future<\/span><span class=\"o\">[<\/span><span class=\"kt\">Int<\/span><span class=\"o\">]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nv\">dbConfig<\/span><span class=\"o\">.<\/span><span class=\"py\">db<\/span><span class=\"o\">.<\/span><span class=\"py\">run<\/span><span class=\"o\">(<\/span><span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">filter<\/span><span class=\"o\">(<\/span><span class=\"nv\">_<\/span><span class=\"o\">.<\/span><span class=\"py\">id<\/span> <span class=\"o\">===<\/span> <span class=\"n\">id<\/span><span class=\"o\">).<\/span><span class=\"py\">delete<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">get<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Long<\/span><span class=\"o\">)<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Future<\/span><span class=\"o\">[<\/span><span class=\"kt\">Option<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nv\">dbConfig<\/span><span class=\"o\">.<\/span><span class=\"py\">db<\/span><span class=\"o\">.<\/span><span class=\"py\">run<\/span><span class=\"o\">(<\/span><span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">filter<\/span><span class=\"o\">(<\/span><span class=\"nv\">_<\/span><span class=\"o\">.<\/span><span class=\"py\">id<\/span> <span class=\"o\">===<\/span> <span class=\"n\">id<\/span><span class=\"o\">).<\/span><span class=\"py\">result<\/span><span class=\"o\">.<\/span><span class=\"py\">headOption<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n\n  <span class=\"k\">def<\/span> <span class=\"nf\">listAll<\/span><span class=\"k\">:<\/span> <span class=\"kt\">Future<\/span><span class=\"o\">[<\/span><span class=\"kt\">Seq<\/span><span class=\"o\">[<\/span><span class=\"kt\">User<\/span><span class=\"o\">]]<\/span> <span class=\"k\">=<\/span> <span class=\"o\">{<\/span>\n    <span class=\"nv\">dbConfig<\/span><span class=\"o\">.<\/span><span class=\"py\">db<\/span><span class=\"o\">.<\/span><span class=\"py\">run<\/span><span class=\"o\">(<\/span><span class=\"nv\">users<\/span><span class=\"o\">.<\/span><span class=\"py\">result<\/span><span class=\"o\">)<\/span>\n  <span class=\"o\">}<\/span>\n<span class=\"o\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"3-add-database-evolution\">3. Add database evolution<\/h4>\n\n<p>Database evolutions allow you to declare migrations when you add new tables, modify them, or delete some.\nSince the database should be empty for now, evolutions will take care of adding the User table.<\/p>\n\n<p><a href=\"https:\/\/www.playframework.com\/documentation\/2.4.x\/Evolutions\">Play evolutions<\/a> include a <code class=\"language-plaintext highlighter-rouge\">Ups<\/code> and a <code class=\"language-plaintext highlighter-rouge\">Downs<\/code> sections. The <code class=\"language-plaintext highlighter-rouge\">Downs<\/code> section can be applied if Play thinks something went wrong and needs to rollback. You can disable this feature - may be danger to have downs in production - in the configurations with<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>play.evolutions.autoApplyDowns=false\n<\/code><\/pre><\/div><\/div>\n\n<p>The evolution scripts should be in the directory <code class=\"language-plaintext highlighter-rouge\">conf\/evolutions\/%databaseName%<\/code> with the name of the scripts stating at <strong>1.sql<\/strong>, incrementing at each evolution. Play keeps track of which evolutions has already applied in a table called <em>play_evolutions<\/em>.<\/p>\n\n<p>Our evolution script, <code class=\"language-plaintext highlighter-rouge\">1.sql<\/code>:<\/p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code># User schema\n\n# --- !Ups\ncreate table `user` (\n  `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n  `first_name` TEXT NOT NULL,\n  `last_name` TEXT NOT NULL,\n  `mobile` BIGINT NOT NULL,\n  `email` TEXT NOT NULL\n)\n\n# --- !Downs\ndrop table `user`\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"play-with-it\">Play with it<\/h3>\n\n<p>Now everything should be up and running ! Also, the final version is available at <a href=\"https:\/\/github.com\/pedrorijo91\/play-slick3-steps\/tree\/step3\">Github<\/a> in case you want to check something.<\/p>\n\n<p>Try it out at <code class=\"language-plaintext highlighter-rouge\">localhost:9000<\/code>, add more persistent data, and your own slick queries, and start creating your own applications.<\/p>\n","pubDate":"Mon, 09 Nov 2015 23:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/play-slick\/","guid":"https:\/\/pedrorijo.com\/blog\/play-slick\/"},{"title":"Playing with Instagram API","description":"<p><span class=\"dropcap\">F<\/span>or those who don\u2019t know, the <a href=\"https:\/\/www.playframework.com\/\">Play Framework<\/a> is the standard web framework for Scala (also available to Java), and it is similar to many other MVC frameworks, such as <a href=\"http:\/\/projects.spring.io\/spring-framework\/\">Spring MVC<\/a>, <a href=\"http:\/\/rubyonrails.org\/\">Ruby on Rails<\/a>, <a href=\"https:\/\/www.djangoproject.com\/\">Django<\/a>, and so on.<\/p>\n\n<p>And it has been a while since I\u2019ve been wanting to play a little bit and experiment the Play Framework.\nUnfortunately, I never had the time, or any good idea to start with it. And simply going through the available tutorials is not enough to learn about a library\/framework, in my opinion.<\/p>\n\n<p>But a few weeks ago I just found out an amazing website! It\u2019s is called <a href=\"http:\/\/likecreeper.com\/\">Like Creeper<\/a>.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/like-creeper.gif\" alt=\"Like Creeper\" title=\"Like Creeper\" width=\"500px\" \/><\/p>\n\n<p>It is a fairly simple idea, but real fun: making random likes in old photos from your friends in Instagram!<\/p>\n\n<p>So, how does it works?<\/p>\n\n<ol>\n  <li>First it will ask you for access to your Instagram account;<\/li>\n  <li>Then, it will choose one of your friends (from those who you follow);<\/li>\n  <li>After that, it will pick an old photo randomly from the chosen friend;<\/li>\n  <li>Finally it posts a like in the chosen photo.<\/li>\n  <li>Now your friend will receive the notification that you liked its photo from a long time ago and he will be all like WTF!?!?!<\/li>\n<\/ol>\n\n<p>Just give it a try!<\/p>\n\n<h3 id=\"insta-roulette\">Insta Roulette<\/h3>\n\n<p>After that, and thinking that it will be a simple but funny task, I decided to clone it.\nAnd so I started the <a href=\"https:\/\/github.com\/pedrorijo91\/instaRoulette\">Insta Roulette<\/a>.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/instaRoulette-home.png\" alt=\"Insta Roulette home\" title=\"Insta Roulette home\" width=\"500px\" \/><\/p>\n\n<p>My idea was not only to clone Like Creeper, but to try to introduce a few changes. Maybe it would be cool to challenge your friends. Something like:<\/p>\n\n<ul>\n  <li>You would access the app<\/li>\n  <li>You would choose a friend to challenge<\/li>\n  <li>Your random like would be shown to you (or maybe just at the end?)<\/li>\n  <li>If your friend accepted the challenge it would be chosen a random photo for him to like, and both likes would be posted<\/li>\n  <li>If your friend declined the challenge, no like would be posted<\/li>\n<\/ul>\n\n<p>I\u2019ve made it to the first milestone, with the random like, very similar to Like Creep. Unfortunately, some problems have arisen, making it impossible to continue the project: Instagram restricted the access to most its API to business applications. This lead to the impossibility to deploy the app for general use, making me deciding to abort the development for now.<\/p>\n\n<p>The design is fairly incomplete, but I would have spend more time on that if the app could be deployed. If Instagram decides to open its API again I will get back to finish this idea.<\/p>\n\n<h4 id=\"how-to-overcome\">How to overcome<\/h4>\n\n<p>If you want to try the roulette for your own account just grab the project from <a href=\"https:\/\/github.com\/pedrorijo91\/instaRoulette\">Github<\/a>. After cloning the project, get an access token and replace it in <code class=\"language-plaintext highlighter-rouge\">app\/services\/Instagram#getAccessToken<\/code> method.<\/p>\n\n<p>You can get a token using the <a href=\"https:\/\/apigee.com\/console\/instagram\">dev console<\/a>, providing authorization, making any endpoint call, and inspecting the outgoing request, looking for the access token.<\/p>\n\n<p>Now you just need to follow the instructions available in the repository to run the project.\n<br \/>A screenshot from the final screen is available right below as an example:<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/instaRoulette-result.png\" alt=\"Insta Roulette result\" title=\"Insta Roulette result\" width=\"800px\" \/><\/p>\n\n<h3 id=\"instagram-stats\">Instagram stats<\/h3>\n\n<p>Another app using Instagram API I\u2019ve crossed lately is one of those smartphone apps that display some statistics about your Instagram account. Besides the number of followers\/followings, some will display users who don\u2019t follow you back, ghost followers - I guess those who never liked\/commented your photos - and many others. The problem is that those apps don\u2019t display the full results unless you pay.<\/p>\n\n<p>Since I already had the structure for dealing with the Instagram API - from <a href=\"https:\/\/github.com\/pedrorijo91\/instaRoulette\">Insta Roulette<\/a> - I implemented some of those statistics:<\/p>\n\n<ul>\n  <li>Users you follow<\/li>\n  <li>Followers<\/li>\n  <li>Followers you follow<\/li>\n  <li>Users you follow but don\u2019t follow you back<\/li>\n  <li>Users who follow you, but you don\u2019t follow back<\/li>\n  <li>Pending incoming requests (in case you have a private account)<\/li>\n<\/ul>\n\n<p align=\"center\"><img src=\"\/assets\/img\/instaStats-result.png\" alt=\"Instagram Stats result\" title=\"Instagram Stats result\" width=\"800px\" \/><\/p>\n\n<p>It\u2019s an handy app for me, as I like to maintain my Instagram account fairly restricted, and maybe it will turn out to be handy for you too. The code is also available at <a href=\"https:\/\/github.com\/pedrorijo91\/instagram-stats\">Github<\/a>.<\/p>\n\n<h4 id=\"instagram-api-access-restriction\">Instagram API access restriction<\/h4>\n\n<p>Once again, the restriction by Instagram API made this project impossible to complete and deploy for general usage. Follow the previous instructions to test this project by yourself just as in <strong>Insta Roulette<\/strong>.<\/p>\n","pubDate":"Sun, 20 Sep 2015 16:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/play-instagram\/","guid":"https:\/\/pedrorijo.com\/blog\/play-instagram\/"},{"title":"Mac and homebrew, the perfect marriage","description":"<p><span class=\"dropcap\">L<\/span>ast week, on September 1<sup>st<\/sup>, I started a new adventure on <a href=\"https:\/\/www.codacy.com\/\">Codacy<\/a>.<\/p>\n\n<p>Codacy is an automated code review tool that allows developers to improve code quality and monitor technical debt. It aims to improve the code review process. To achieve such goal, not only automates the code review process, but also integrates with existing project management tools such <a href=\"https:\/\/bitbucket.org\/\">Bitbucket<\/a>, <a href=\"https:\/\/github.com\/\">Github<\/a>, <a href=\"https:\/\/travis-ci.org\/\">Travis CI<\/a>, and so on.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/codacy-homepage.jpg\" alt=\"Codacy homepage\" title=\"Codacy homepage\" width=\"500px\" \/><\/p>\n\n<p>As usual, when getting a new job, you have to configure your workstation once again. Having a mac, you do not have that native amazing tool as you have in Linux distributions: <code class=\"language-plaintext highlighter-rouge\">apt-get<\/code> (or <code class=\"language-plaintext highlighter-rouge\">yum<\/code>, or some other equivalent), a command-line tool for handling packages, that allows you to install most of your software easily.<\/p>\n\n<p>Of course, if you are a mac user, you are probably aware of <a href=\"http:\/\/brew.sh\/\">Homebrew<\/a>, the equivalent command-line tool for mac. Using <code class=\"language-plaintext highlighter-rouge\">brew<\/code> you can get a lot of software installed in your mac. Nevertheless, there is still plenty of software you have to download for yourself, open the installer, and drag to your <code class=\"language-plaintext highlighter-rouge\">Applications<\/code> folder. And that sucks. I don\u2019t want to open dozens of websites, look for the latest version, download it, and drag them to the <code class=\"language-plaintext highlighter-rouge\">Applications<\/code> folder. I want to have a script that can install all the software I need, without my intervention.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/brew-install-git.jpg\" alt=\"brew install git\" title=\"brew install git\" width=\"600px\" \/><\/p>\n\n<p>Fortunately, I got to meet <a href=\"https:\/\/caskroom.github.io\/\">Homebrew Cask<\/a>, an extension to Homebrew that promises to end with the drag to install action. To install it, just type in your terminal:<\/p>\n\n<p><code>brew install caskroom\/cask\/brew-cask<\/code><\/p>\n\n<p>And <i>voil\u00e0<\/i>, you are ready to install all the software you need !\n&lt;\/br&gt;\nFor instance, you can install <a href=\"http:\/\/www.skype.com\">Skype<\/a>, <a href=\"https:\/\/slack.com\/\">Slack<\/a>, <a href=\"https:\/\/www.hipchat.com\/\">Hipchat<\/a>, <a href=\"https:\/\/www.dropbox.com\/\">Dropbox<\/a>, <a href=\"https:\/\/www.jetbrains.com\/idea\/\">Intellij<\/a>, <a href=\"http:\/\/www.videolan.org\/vlc\/\">Vlc<\/a>, even <a href=\"https:\/\/popcorntime.sh\/\">Popcorn-time<\/a> ! Just find out what\u2019s available at <a href=\"https:\/\/caskroom.github.io\/search\">Cask Search<\/a> !<\/p>\n\n<p>Just select those you need and recommend those you think it could be handy.<\/p>\n","pubDate":"Mon, 07 Sep 2015 18:30:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/mac-and-brew\/","guid":"https:\/\/pedrorijo.com\/blog\/mac-and-brew\/"},{"title":"Lighthouse keeper - yet another ping","description":"<p><span class=\"dropcap\">I<\/span>t has been a while since my last post, but between some side projects, summer vacation, and personal hobbies, it hasn\u2019t been exactly easy to get time to write something.<\/p>\n\n<p>Today I want to talk about another small project I finished not long time ago!<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/GYC2015-logo.png\" alt=\"GYC2015\" title=\"GoYouth Conference 2015\" width=\"300px\" \/><\/p>\n\n<p>It all started at <a href=\"http:\/\/www.goyouthconf.com\/\">Go Youth Conference 2015<\/a> (or GYC 2015) last April.\nGYC is an unique conference, created by a group of young entrepreneurs in 2012, with one clear goal, to inspire and empower young people to create their own future. Where entrepreneurs can exchange ideas, start meaningful conversations and be introduced to powerful content that can help them to thrive and take charge of their economic future.\nThis year edition presented us an excellent line-up, containing speakers such as:<\/p>\n\n<ul>\n  <li><a href=\"https:\/\/twitter.com\/primdahl\">Morten Primdahl<\/a>, Co-Founder and CTO at <a href=\"https:\/\/www.zendesk.com\/\">Zendesk<\/a>;<\/li>\n  <li><a href=\"http:\/\/www.burthelm.com\/\">Burt Helm<\/a>, Senior Contributing Writer at <a href=\"http:\/\/www.inc.com\/\">Inc.<\/a>;<\/li>\n  <li><a href=\"https:\/\/twitter.com\/kmin\">Kathryn Minshew<\/a>, Co-Founder and CEO at <a href=\"https:\/\/www.themuse.com\/\">The Muse<\/a>;<\/li>\n  <li><a href=\"https:\/\/uk.linkedin.com\/in\/filipacneto\">Filipa Neto<\/a>, Co-Founder and Managing Director at <a href=\"http:\/\/chic-by-choice.com\">Chic By Choice<\/a>;<\/li>\n  <li><a href=\"https:\/\/twitter.com\/orarbel\">Or Arbel<\/a>, Co-founder and CEO at <a href=\"https:\/\/www.justyo.co\/\">Yo<\/a>;<\/li>\n  <li>and even <a href=\"https:\/\/hk.linkedin.com\/in\/raychan\/pt\">Ray Chan<\/a>, Co-Founder and CEO at <a href=\"http:\/\/9gag.com\/\">9GAG<\/a><\/li>\n<\/ul>\n\n<p align=\"center\"><img src=\"\/assets\/img\/yo-logo.png\" alt=\"Yo\" title=\"Yo\" width=\"200px\" \/><\/p>\n\n<p>And what really made this project happen was the talk by Or Arbel. In his talk he introduced Yo. Do you remember Yo?&lt;\/br&gt;\nYo is a mobile app launched a little more than a year ago (early 2014). It made a huge impact: first it seemed the next big thing, the next social network. Then, it seemed the most pathetic mobile app someone ever did. It had a single functionality: send a \u2018yo\u2019 (a notification, a Snapchat without image, video, text, or any other thing) to someone else - currently it is possible to incorporate links, images, and GPS coordinates.\n<a href=\"http:\/\/www.businessinsider.com\/whats-happened-to-7-million-app-yo-now-that-the-hype-has-died-2014-9\">Business Insider<\/a> and <a href=\"http:\/\/www.entrepreneur.com\/article\/243311\">Entrepreneur<\/a> wrote some interesting articles about Yo, just check them !<\/p>\n\n<p>But Or Arbel made me (and probably everybody in the audience) see the true power of Yo: Yo could replace those 5 seconds calls just to say \u201cHey man, I\u2019m already at your door to pick you up, just hurry up\u201d, or \u201cHey mom, I\u2019m leaving school now. I\u2019ll arrive home in 10 minutes\u201d. Even better, it could work as a notification for some service, like a blog. The blog owner (or any automated mechanism) would send a Yo to all its subscribers and they would know a new post had just been released. Well, everything seems nice, but I could use my RSS reader for that, or making a simple (probably free) phone call to my friends and mom\u2026<\/p>\n\n<p>But that\u2019s not the truly power of Yo: Yo is a notification infrastructure that only requires a publisher, and some subscribers. The most powerful example Or Arbel gave us was from a conflict country (I think is Iraq, but not sure) which wanted to implemented a civilian notification channel for missile alert for years, and using Yo it was able to implement it with almost no effort and in very little time.<\/p>\n\n<p>During his talk, Or Arbel told us about Yo API, and that it would have great new features in the coming months, so I decided to take a look at <a href=\"http:\/\/docs.justyo.co\/docs\">Yo API<\/a>. Well, it was simple, and it would be fun to play a bit with it. But what could I do with Yo API? The first idea that crossed my mind was a small python script that would check if a specified URL is responding. If not, it would notify someone (possibly the owner\/manager) through Yo. And so was born <a href=\"https:\/\/github.com\/pedrorijo91\/lighthouse-keeper\">lighthouse-keeper<\/a> !<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/lighthouse-keeper-github.png\" alt=\"lighthouse-keeper repository\" title=\"lighthouse-keeper repository\" width=\"800px\" \/><\/p>\n\n<p>Lighthouse-keeper reads several properties from a configuration file:<\/p>\n\n<ul>\n  <li>URL that should be checked<\/li>\n  <li>ping definitions (time between each ping request, maximum of errors before notifying, and connection timeout)<\/li>\n  <li>yo definitions (api token, notifiers, and an optional link to be send in the yo notification)<\/li>\n  <li>email definitions, if you want to notify by email also (server, account, password, recipients, email subject, email body)<\/li>\n<\/ul>\n\n<p>It is a very simple project, one that can be done easily in a weekend, used just to play with Yo API. It is not error safe, many error cases are not being checked. So, if you plan to use it, you\u2019ll probably have to test it a bit and make some fixes.<\/p>\n\n<p>Feel free to take a look in <a href=\"https:\/\/github.com\/pedrorijo91\/lighthouse-keeper\">github<\/a>.<\/p>\n","pubDate":"Sun, 26 Jul 2015 20:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/lighthouse-keeper\/","guid":"https:\/\/pedrorijo.com\/blog\/lighthouse-keeper\/"},{"title":"Seven Languages in Seven Weeks - Book review","description":"<p><span class=\"dropcap\">R<\/span>ecently I\u2019ve finished reading the book \u2018Languages in Seven Weeks\u2019. It is part of <a href=\"https:\/\/pragprog.com\/categories\/7in7\">Seven in Seven series<\/a> and it approaches seven different programming languages: <a href=\"https:\/\/www.ruby-lang.org\/en\/\">Ruby<\/a>, <a href=\"http:\/\/iolanguage.org\/\">IO<\/a>, <a href=\"http:\/\/www.swi-prolog.org\/\">Prolog<\/a>, <a href=\"http:\/\/scala-lang.org\/\">Scala<\/a>, <a href=\"http:\/\/www.erlang.org\/\">Erlang<\/a>, <a href=\"http:\/\/clojure.org\/\">Clojure<\/a>, and <a href=\"https:\/\/www.haskell.org\/\">Haskell<\/a>.<\/p>\n\n<p>The publisher, <a href=\"https:\/\/pragprog.com\/\">The Pragmatic Bookshelf<\/a>, introduces this book by making reference to a recommendation by <a href=\"https:\/\/pragprog.com\/the-pragmatic-programmer\">The Pragmatic Programmer<\/a>, which states \u201cYou should learn a programming language every year\u201d, and suggesting that this book will make you learn <em>seven<\/em> new languages in about two months.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/7lang7weeks.jpg\" alt=\"7lang7weeks\" title=\"7 Languages in 7 Weeks cover\" width=\"400px\" \/><\/p>\n\n<p>First you need to understand that you are obviously not going to learn a whole language with this book. It\u2019s impossible to master a programming language in a single week (as you probably already know). In one week you can get through the basics, you can even get to some advanced language-specific features if you are a experienced programmer, but there\u2019s a lot to explore until you master a language.<\/p>\n\n<p>This book will present you seven distinct languages, its features, as well as its strengths and weaknesses, and will also make you reason about several language components and understand decisions behind each programming language. It will give you just a <em>\u201cflavour\u201d<\/em> of each language - more than an Hello World, but definitely not the whole of the language. It will present not only programming languages but also new paradigms like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Functional_programming\">Functional Programming<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Logic_programming\">Logic Programming<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Object-oriented_programming\">Object Oriented Programming<\/a>, and also combined paradigms like we see in Scala with Object Oriented and Functional Programming combined together.<\/p>\n\n<p>Each chapter is dedicated to one language, and it\u2019s split into five sections:<\/p>\n\n<ul>\n  <li>A brief introduction to the language and a very interesting interview with the language creator.<\/li>\n  <li>\u2018Day 1\u2019 is all about syntax, REPL, and some very basic concepts.<\/li>\n  <li>\u2018Day 2\u2019 usually starts introducing some more complex language features like data structures, modules, classes and so on.<\/li>\n  <li>\u2018Day 3\u2019 presents you language advanced features in order to solve a proposed problem. The problem is chosen to show in which kind of problems the language provides an adequate set of features. For instance, in the Prolog chapter the final problem is a Sudoku solver due to Prolog efficiency in solving <a href=\"http:\/\/en.wikipedia.org\/wiki\/Constraint_satisfaction_problem\">CSPs<\/a>, the Ruby chapter provides a problem focused on meta programming and dynamic typing, while Haskell problem is all about monads.<\/li>\n  <li>A conclusion section, with a small resume of the language, its core strengths and weaknesses.<\/li>\n<\/ul>\n\n<p>Despite all the amazing things this book accomplish there are some issues that could have been avoided in my opinion:<\/p>\n\n<ul>\n  <li>Each language is compared to a fictional character, a decision that may have not been that nice. At least for me, some of the comparisons were not very obvious (some of them because I didn\u2019t knew the film\/character), leading you to miss some information the author though it was sending in such an easy way.<\/li>\n  <li>The name of the sections could be clearer about what will you learn in those pages. It could make easier to understand what I\u2019m reading with a proper contextualisation given by the section title.<\/li>\n  <li>As the end of the book was becoming closer, I started thinking that the book was focusing in the same features and problems again. Maybe because it were features I had already learn, but I started thinking that I was not learning anything new in some of the final sections.<\/li>\n<\/ul>\n\n<p>In short, this book will not only make you know and understand language features that you probably don\u2019t mess with everyday in your current job, but it will also make you understand which programming language fits a specific problem. It has increased my desire in learning a new language and it probably will make me spend some time with Ruby and Clojure. Still, this book assumes that you will do much work by your own, so don\u2019t expect just to read your daily chapter and go to sleep. Try to search and learn by yourself, complementing the book and you will certainly enjoy those seven weeks!<\/p>\n\n<p>Among the several new features, I really liked to learn about Erlang\u2019s \u2018<em>let-it-crash<\/em>\u2019 philosophy for building fault-tolerant systems. It\u2019s something that I\u2019ve never heard until now. I\u2019ve been across with unification (Prolog), pattern matching (Scala and <a href=\"http:\/\/smlnj.org\/\">ML<\/a>), meta-programming (Java), actors (<a href=\"http:\/\/akka.io\/\">Scala Akka<\/a>), but let-it-crash philosophy is something really new for me and it surely opened my mind.<\/p>\n\n<p>If you want to, take a look at my solutions and use them to compare with your own (or if you are just curious about how does it look each language) in my <a href=\"https:\/\/github.com\/pedrorijo91\/7lang7weeks\">github repo<\/a>.<\/p>\n","pubDate":"Thu, 21 May 2015 15:15:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/seven-languages-seven-weeks\/","guid":"https:\/\/pedrorijo.com\/blog\/seven-languages-seven-weeks\/"},{"title":"Bulletproof Commits","description":"<p><span class=\"dropcap\">H<\/span>ave you ever committed code that made you feel ashamed? Maybe, for instance, a print statement you used for debugging just because you were too lazy to use the debugger? Maybe you even had that crazy idea of using a <em>not so pretty<\/em> print message? (Don\u2019t worry, we all felt desperate to that point.)<\/p>\n\n<p>If the project you are working on has strong code review practices then, those print statements should get caught before going to production. Nevertheless, the code review process may let pass those pieces of code undetected when the diff set gets too large and there may be some time constraints.<\/p>\n\n<p>One simple solution is to review your own code before committing. How? I\u2019ve found out recently a very useful feature on git, the <em>\u2018git add -p\u2019<\/em> command (if you use some git client I don\u2019t know how to use this feature, but there\u2019s probably an equivalent functionality).\nThis command allows you to \u201cinteractively choose hunks of patch between the index and the work tree and add them to the index\u201d<sup><a href=\"http:\/\/git-scm.com\/docs\/git-add\">1<\/a><\/sup>, giving you a chance to review the difference before adding modified contents to the index.<\/p>\n\n<p>But who has the patience to review every chunk of code carefully? Well, maybe no one?<\/p>\n\n<p><a href=\"https:\/\/github.com\/pedrorijo91\/commit4dummies\">Commit 4 dummies<\/a> is a side project I\u2019ve developed to help me detecting junk code before committing it. It is based on another git feature that allows you to automate such code revision: <a href=\"http:\/\/git-scm.com\/book\/en\/v2\/Customizing-Git-Git-Hooks\">Git Hooks<\/a>.<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/screencapture-commit4dummies.png\" alt=\"commit4dummies\" title=\"Commit 4 dummies project\" width=\"800px\" \/><\/p>\n\n<p>Git Hooks are custom scripts that run on specific events, and there are two groups:<\/p>\n\n<ul>\n  <li><a href=\"http:\/\/git-scm.com\/book\/en\/v2\/Customizing-Git-Git-Hooks#Client-Side-Hooks\">Client-side hooks<\/a>, triggered by operations like committing and merging.<\/li>\n  <li><a href=\"http:\/\/git-scm.com\/book\/en\/v2\/Customizing-Git-Git-Hooks#Server-Side-Hooks\">Server-side hooks<\/a>, which run on network operations, such as receiving pushed commits. <a href=\"https:\/\/travis-ci.org\/\">Travis<\/a>, <a href=\"https:\/\/www.atlassian.com\/software\/jira\">Jira<\/a> and many other code services are based on server-side hooks, also known as webhooks.<\/li>\n<\/ul>\n\n<p>In the <a href=\"http:\/\/git-scm.com\/book\/en\/v2\/Customizing-Git-Git-Hooks\">documentation<\/a> you can learn about the several client-side and server-side hooks. For the purpose of reviewing committing code we focus on <em>\u2018pre-commit\u2019<\/em> hooks. As declared in the documentation, \u201cThe pre-commit hook is run first, before you even type in a commit message\u201d, meaning it\u2019s the perfect tool for our goal.<\/p>\n\n<p>So, how is this hook implemented? The basic idea is to make a <em>\u2018grep\u2019<\/em> search through the diff set for some words that should be defined in the <em>\u2018keywords.conf\u2019<\/em> file. This file is a simple text file, containing, in each line, the file extension and the words to look for. Take a look in this simple <a href=\"https:\/\/github.com\/pedrorijo91\/commit4dummies\/blob\/master\/keywords.conf\">example<\/a>. This file allows anyone to configure the hook to its own needs without much effort.<\/p>\n\n<p>Some worthy details:<\/p>\n\n<ul>\n  <li>The <em>\u2018grep\u2019<\/em> search does not looks for the exact word, meaning that looking for <em>\u2018print\u2019<\/em> could match with <em>\u2018println\u2019<\/em>.<\/li>\n  <li>This hook assumes that you are only looking in the last diff set, meaning that if you are applying the hook to an ongoing project then you should probably make a manual <em>\u2018grep\u2019<\/em> search yourself.<\/li>\n  <li>Only added on edited files in the staging area are considered: removed files are ignored.<\/li>\n  <li>A <em>\u2018git stash\u2019<\/em> and <em>\u2018git stash pop\u2019<\/em> commands are executed to match against staged version of the file, otherwise you could be matching against a version different from the one committing (this operation should be transparent for the developer). This feature differs this hook from most of the available on the web, since this details is usually forgotten.<\/li>\n  <li>For each match the user is prompted for continuation\/abortion, because it may exist some false positives.<\/li>\n  <li>Some coloured feedback is printed to the console<\/li>\n<\/ul>\n\n<blockquote>\n  <p>Note:\nYou can always skip you client-side hooks with <em>\u2018git commit \u2013no-verify\u2019<\/em><\/p>\n<\/blockquote>\n","pubDate":"Tue, 28 Apr 2015 12:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/bulletproof-commits\/","guid":"https:\/\/pedrorijo.com\/blog\/bulletproof-commits\/"},{"title":"And God said: \u201cLet there be light\u201d","description":"<p><span class=\"dropcap\">H<\/span>ey there,<br \/>\n and welcome to my new blog!<\/p>\n\n<p>It has been a while since I got this idea of creating a blog, a place where I could share my nerd stories, and it finally happened. :smiley:<br \/>\nI\u2019m gonna use this blog to communicate with the world and to let you know I am up to.<\/p>\n\n<p><strong>And no, it\u2019s not an April fools joke!<\/strong><\/p>\n\n<p>Hoping to keep you guys with me!<\/p>\n\n<p align=\"center\"><img src=\"\/assets\/img\/may_the_source_be_with_you_white.png\" alt=\"yoda\" title=\"May the source be with you\" width=\"400px\" \/><\/p>\n","pubDate":"Wed, 01 Apr 2015 01:00:00 +0000","link":"https:\/\/pedrorijo.com\/blog\/hello-world\/","guid":"https:\/\/pedrorijo.com\/blog\/hello-world\/"}]}}