Solid And Sustainable Development in Scala

Kazuhiro Sera
Kazuhiro SeraStaff Partner Engineer at Slack Japan
Solid and Sustainable 
Development in Scala 
Kazuhiro Sera @seratch 
ScalikeJDBC / Skinny Framework 
Founder & Lead Developer
Ask Me Later! 
• 3 mags for questioners at the end of this 
session! Don’t miss it! 
2
Who Am I 
• Kazuhiro Sera • @seratch on Twitter/GitHub • Scala enthusiast since 2010 • ScalikeJDBC, Skinny Framework, AWScala 
founder & project lead • A web developer at M3, Inc (We’re a Gold 
Sponsor)
Introduce 
My(Our) Products
ScalikeJDBC 
• scalikejdbc.org • “Scala-like JDBC” • Provides Scala-ish APIs • Started as a better querulous / Anorm • “Just write SQL and get things done” • QueryDSL for smoothness & type-safety • Stable enough: lots of companies already 
use it in production
Dependencies 
// build.sbt or project/Build.scala! 
! 
scalaVersion := “2.11.2” // or “2.10.4”! 
! 
libraryDependencies ++= Seq(! 
“org.scalikejdbc” %% “scalikejdbc” % “2.1.1”,! 
“com.h2database” % “h2” % “1.4.181”,! 
“ch.qos.logback” % “logback-classic” % “1.1.2”! 
)
Basic Usage 
import scalikejdbc._! 
! 
ConnectionPool.singleton(! 
“jdbc:h2:mem:matsuri”, ! 
“user”, “secret”)! 
SQL statement! 
(PreparedStatement) 
! 
DB autoCommit { implicit session =>! 
Side effect ! 
with DB connection 
sql”create table attendee (name varchar(32))”.execute.apply()! 
val name = “seratch”! 
sql”insert into attendee (name) values ($name)”.update.apply()! 
}! 
! 
val names: Seq[String] = DB readOnly { implicit s =>! 
sql”select name from attendee”! 
.map(_.string(“name”)).list.apply()! 
} 
execute/update! 
(JDBC operation) 
Extractor
QueryDSL 
import scalikejdbc._! 
case class Attendee(name: String)! 
object Attendee extends SQLSyntaxSupport[Attendee] {! 
def apply(rs: WrappedResultSet, a: ResultName[Attendee]) = ! 
new Attendee(rs.get(a.name)) 
}! 
! 
implicit val session = AutoSession! 
! 
! 
val a = Attendee.syntax(“a”)! 
val seratch: Option[Attendee] = withSQL {! 
QueryDSL! 
(Mostly SQL) 
Actual SQL Query 
select.from(Attendee as a).where.eq(a.name, “seratch”)! 
}.map(rs => new Attendee(rs, a)).single.apply()! 
! 
// select a.name as n_on_a from attendee a where a.name = ?
Skinny Framework 
• skinny-framework.org • “Scala on Rails” • For Rails / Play1 lovers • 1.0.0 was out on 28th March • Already several experiences in production • Full-stack features: Web infrastructure, 
Scaffold generator, ORM, DB migration, 
JSON stuff, HTTP client, Mail sender, Job 
workers, Assets controller, etc..
Boot in 2 minutes 
! 
// install skinny command! 
brew tap skinny-framework/alt! 
brew install skinny! 
! 
// create app and start! 
skinny new myapp! 
cd myapp! 
skinny run! 
! 
// access localhost:8080 from your browser!
Model (DAO) 
import skinny.orm._! 
Entity 
import scalikejdbc._! 
! 
case class User(id: Long, name: Option[String])! 
! 
// companion: data mapper! 
object User extends SkinnyCRUDMapper[User] {! 
def defaultAlias = createAlias(“u”)! 
def extract(rs: WrappedResultSet, u: ResultName[User])! 
= autoConstruct(rs, u) 
}! 
CRUD Mapper Object! 
! 
(No need to be companion) 
User.findById(123)! 
User.count()! 
User.createWithAttributes(‘name -> “Alice”)! 
User.updateById(123).withAttributes(‘name -> “Bob”)! 
User.deleteBy(sqls.eq(u.name, “Bob”)) 
Smooth APIs
Controller + Route 
package controller! 
class UsersController extends ApplicationController {! 
def showUsers = {! 
set(“users”, User.findAll())! 
render(“/users/index”) 
} 
}! 
! 
// Routings! 
object Controllers {! 
Set value in request scope! 
(Visible in views) 
Expects “src/main/webapp/! 
WEB-INF/views/users/index.html.ssp” 
val users = new UsersController with Routes {! 
get(“/users/”)(showUsers).as(‘showUsers) 
}! 
def mount(ctx: ServletContext): Unit = {! 
users.mount(ctx)! 
} 
}
View Template 
// src/main/webapp/WEB-INF/views/users/index.html.ssp! 
! 
<%@val users: Seq[User] %>! 
! 
<table class=“table”>! 
#for (user <- users)! 
<tr>! 
<td>${user.id}</td>! 
<td>${user.name}</td>! 
</tr>! 
#end! 
</table> 
import from request scope 
Loop, if/else syntax! 
in Scalate
Web Development 
• Interactive feedback loop is most 
important especially when changing UI • Actually Scala compilation is so slow that 
waiting view templates compilation makes 
developers much stressed • Skinny doesn’t compile all the view 
templates when developing (unlike Twirl)
My Good Parts 
for Solid and Safe 
Development
My Good Parts 
•Simplified Class-based OOP And 
Immutable Data Structure 
•Working On Problems Without 
Overkill Abstraction 
•Writing Tests Without Question 
•Keep Infrastructure Lightweight 
•No Surprises For Newcomer
Simplified Class-based 
OOP 
And Immutable 
Data Structure
Class-based OOP 
• Already so popular (Java, Ruby, Python ..) • Old style is friendly with mutability (e.g. 
setters, bang methods), but that’s not a 
prerequisite • OOP can be more solid and safer by 
keeping immutability and avoiding 
inheritance anti-patterns
Scala or Java 8? 
• Scala case class is simpler than Java 
beans with (great) Lombok • Scala high-order functions are simpler 
than Java 8 Stream API • Immutability is well-treated in Scala • Fairness: Java decisively beats Scala in 
comparison with compilation speed..
Immutability 
• Do away with mutable states • Re-assignment? No way! Don’t use `var` • Immutability makes your apps not only 
scalable but also more solid • When you modify a case class, call 
#copy() and return new state instead of 
using setters for mutability inside
Immutable Entity 
// entity with behaviors! 
case class User(id: Long, name: Option[String])! 
extends SkinnyRecord[User] {! 
override def skinnyCRUDMapper = User 
}! 
// data mapper! 
object User extends SkinnyCRUDMapper[User] {! 
override def defaultAlias = createAlias(“u”)! 
override def extract(rs: WrappedResultSet, u: ResultName[User])! 
= autoConstruct(rs, u) 
}! 
! 
val noNames: Seq[User] = User.where(‘name -> “”).apply()! 
val anons: Seq[User] = noNames.map { user => ! 
user.copy(name = “Anonymous”).save()! 
} 
Both of “noNames” and 
“anons” are immutable
Trait Chaos 
• Mixing traits can show you terrible chaos • We should have self-discipline • Prefer `override` modifier to detect API 
changes when mixing many traits • Collect the same sort of traits and place 
them in same place to avoid code 
duplication or unwanted complexity
Web Controller 
package controller! 
class MainController extends ApplicationController ! 
with concern.TimeLogging {! 
def index = logElapsedTime { render(“/main/index”) }! 
}! 
! 
// for controllers! 
package controller.concern! 
trait TimeLogging { self: SkinnyController with Logging =>! 
The “concern” just follows Rails style. 
Anyway, naming should be simple and! 
easy-to-understand for anyone 
def millis: Long = System.currentTimeMillis ! 
def logElapsedTime[A](action: => A): A = {! 
val before = millis! 
val result = action! 
logger.debug(“Elapsed time: ${millis - before} millis”)! 
result 
}! 
}
Coding Style Tips 
• Use sbt-scalariform without question 
(similar: go-lang’s fmt) • Don’t toss similar classes or traits into 
single scala file except `sealed` pattern • Don’t place classes under different 
package directory (although it’s possible) • Do you really need cake pattern? • Prefer eloquent method signature than 
explaining a lot in scaladocs
Working On 
Problems Without 
Overkill Abstraction
The Real As-Is 
• Abstraction often improves things, but 
that’s not always the best way to solve 
real-world problems • I/O issue is a typical case that we should 
comprehend problems as-is • Database access / SQL is not a collection 
but just an external I/O operation • Overkill abstraction makes your code 
difficult to maintain for other developers
Don’t Hide the SQL 
• “You don’t need another DSL to access 
relational databases” - Anorm • You must recognize what is working 
effectively in the SQL layer • Utility to write DAO easily is fine but 
hiding SQL is not good • Need to grab the cause from raw queries 
when dealing with troubles (comfortable 
logging also can help)
SQL Ops As-Is 
// A programmer belongs to a company and has several skills! 
! 
implicit val session = AutoSession! 
! 
val p: Option[Programmer] = withSQL {! 
I believe everybody can 
understand this code 
select.from(Programmer as p)! 
.leftJoin(Company as c).on(p.companyId, c.id)! 
.leftJoin(ProgrammerSkill as ps).on(ps.programmerId, p.id)! 
.leftJoin(Skill as s).on(ps.skillId, s.id)! 
.where.eq(p.id, 123).and.isNull(p.deletedAt)! 
}! 
.one(rs => Programmer(rs, p, c))! 
Extracts one-to-many 
.toMany(rs => Skill.opt(rs, s))! 
relationships here 
.map { (programmer, skills) => programmer.copy(skills = skills) }! 
.single! 
.apply()
Skinny ORM 
• ORM built on ScalikeJDBC • Highly inspired by Rails ActiveRecord • SQL queries for CRUD apps are common 
enough, so it’s reasonable to avoid writing 
mostly same code everywhere • Skinny ORM doesn't prevent you from 
using ScaikeJDBC APIs directly • A part of Skinny Framework but you can 
use it in Play apps too
Dependencies 
// build.sbt or project/Build.scala! 
! 
scalaVersion := “2.11.2” // or “2.10.4”! 
! 
libraryDependencies ++= Seq(! 
//“org.scalikejdbc” %% “scalikejdbc” % “2.1.1”,! 
“org.skinny-framework” %% “skinny-orm” % “1.3.1”,! 
“com.h2database” % “h2” % “1.4.181”,! 
“ch.qos.logback” % “logback-classic” % “1.1.2”! 
)
Mappers 
// entities! 
case class Company(id: Long, name: String)! 
case class Employee(id: Long, name: String,! 
companyId: Long, company: Option[Company])! 
! 
// mappers! 
object Company extends SkinnyCRUDMapper[Company] {! 
def extract(rs: WrappedResultSet, rn: ResultName[Company]) =! 
autoConstruct(rs, rn) 
}! 
object Employee extends SkinnyCRUDMapper[Employee] {! 
def extract(rs: WrappedResultSet, rn: ResultName[Employee]) =! 
autoConstruct(rs, rn, “company”)! 
// simple association definition! 
lazy val companyRef = belongsTo[Company](! 
Company, (e, c) => e.copy(company = c)) 
}
Reasonable? 
Right, these CRUD operations are not SQL-ish. However, I believe 
they’re reasonable because these patterns are already common enough. 
! 
! 
val companyId = Company.createWithAttributes(‘name -> “Sun”)! 
val empId = Employee.createWithAttributes(! 
‘name -> “Alice”, ‘companyId -> companyId)! 
! 
val emp: Option[Employee] = Employee.findById(empId)! 
val empWithCompany: Option[Employee] = ! 
Employee.joins(companyRef).findById(123)! 
! 
Company.updateById(companyId).withAttributes(‘name -> “Oracle”)! 
! 
val e = Employee.defaultAlias! 
Employee.deleteBy(sqls.eq(e.id, empId))! 
Using ScalikeJBDC API! 
Company.deleteById(companyId) 
is also possible
Writing Tests 
Without 
Question
Not Only Compiler 
• It’s true that compiler helps you by 
detecting mistakes in coding • Writing tests is a reasonable way to verify 
your code meets requirements / 
specifications as expected • You can’t skip automated tests even if 
your apps are written in Scala
scoverage 
• At this time, the only option available for 
us is scoverage (SCCT inheritor) • Add the dependency into your projects 
right now if you don’t use it yet
Keep 
Infrastructure 
Lightweight
Avoid SBT Hacks 
• sbt is not so easy for Scala newbies, 
upgrading sbt is all the more so • Play depends on sbt version (e.g. Play 2.1 
w/ sbt 0.12), upgrading Play is about not 
only Play API changes but sbt things • Your own sbt plugins/hacks make your 
projects difficult to maintain for a long 
period and involve others • Don’t try to do everything there
Skinny TaskRunner 
• Just want a simple and “rake”-like task 
runner (no sbt plugin) • Simplistic but pragmatic idea: “mainClass” 
of “task” sbt project can be dispatcher of 
task runner system • Tasks are written in Scala (no sbt plugin) • Not only writing code but upgrading 
scala/sbt version become pretty easy
Tasks 
// sbt settings! 
// mainClass := Some("TaskRunner")! 
! 
// task/src/main/scala/TaskRunner.scala! 
object TaskRunner extends skinny.task.TaskLauncher {! 
register("assets:precompile", (params) => {! 
val buildDir = params.headOption.getOrElse(“build")! 
// AssetsPrecompileTask is a Scala object! 
skinny.task.AssetsPrecompileTask.main(Array(buildDir))! 
})! 
}! 
Pure Scala function! 
! 
// skinny task:run assets:precompile [dir] 
task name 
mainClass as the dispatcher
Use Only Essentials 
• The same issue as Ruby gems, what’s 
worse, Scala’s eco-system is still so 
smaller than Ruby’s one • Binary incompatibility makes existing 
libraries outdated every Scala major 
version release • Are you really ready to fork them? • Using Java assets (e.g. commons) 
internally is also worth thinking about
No Surprises 
for Newcomer
Can Feel Welcome? 
• Is joining your Scala projects easy? Can 
newcomer understand overview at once? • Don’t stick to doing on the sbt, don’t 
disfavor using other tools (e.g. Grunt) • Well-known style (e.g. Rails style) is 
preferred for collaborative works • Is asynchronosity really required now? • Indeed, your DSL is very simple but easy 
to modify them (for others)?
Newcomers may not 
know Scala well. 
Attract them to Scala! 
(Don’t scare them)
AMA! #ScalaMatsuri2 
• Unconference tomorrow • “Ask Me Anything” • ScalikeJDBC • Skinny Framework • AWScala • Anything else!
Questions?
Questions?
Questions?
Thanks 
• Amazing “Maturi Urakata” (the 
conference volunteer staff) • Great invited speakers • You all here!
1 of 48

Recommended

Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一 by
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一scalaconfjp
3.7K views37 slides
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング by
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
2.9K views42 slides
The Evolution of Scala / Scala進化論 by
The Evolution of Scala / Scala進化論The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論scalaconfjp
5.2K views37 slides
From Ruby to Scala by
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scalatod esking
7.9K views41 slides
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう! by
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!scalaconfjp
3.2K views58 slides
How Scala code is expressed in the JVM by
How Scala code is expressed in the JVMHow Scala code is expressed in the JVM
How Scala code is expressed in the JVMKoichi Sakata
8.3K views89 slides

More Related Content

What's hot

Scala @ TechMeetup Edinburgh by
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
1.1K views28 slides
55 New Features in Java 7 by
55 New Features in Java 755 New Features in Java 7
55 New Features in Java 7Boulder Java User's Group
70.9K views63 slides
Node.js vs Play Framework (with Japanese subtitles) by
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
42.5K views163 slides
[Start] Scala by
[Start] Scala[Start] Scala
[Start] Scala佑介 九岡
3.2K views86 slides
Scala Introduction by
Scala IntroductionScala Introduction
Scala IntroductionAdrian Spender
3.2K views76 slides
Java 7 Whats New(), Whats Next() from Oredev by
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevMattias Karlsson
2.2K views84 slides

What's hot(20)

Scala @ TechMeetup Edinburgh by Stuart Roebuck
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
Stuart Roebuck1.1K views
Node.js vs Play Framework (with Japanese subtitles) by Yevgeniy Brikman
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
Yevgeniy Brikman42.5K views
Java 7 Whats New(), Whats Next() from Oredev by Mattias Karlsson
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from Oredev
Mattias Karlsson2.2K views
Concurrency in Scala - the Akka way by Yardena Meymann
Concurrency in Scala - the Akka wayConcurrency in Scala - the Akka way
Concurrency in Scala - the Akka way
Yardena Meymann3.6K views
Extending Oracle E-Business Suite with Ruby on Rails by Raimonds Simanovskis
Extending Oracle E-Business Suite with Ruby on RailsExtending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on Rails
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees) by Stephen Chin
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
Stephen Chin190.7K views
Akka and the Zen of Reactive System Design by Lightbend
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
Lightbend10K views
Building Concurrent WebObjects applications with Scala by WO Community
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with Scala
WO Community918 views
JavaOne 2011 - JVM Bytecode for Dummies by Charles Nutter
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
Charles Nutter8K views
Fast Web Applications Development with Ruby on Rails on Oracle by Raimonds Simanovskis
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
User defined-functions-cassandra-summit-eu-2014 by Robert Stupp
User defined-functions-cassandra-summit-eu-2014User defined-functions-cassandra-summit-eu-2014
User defined-functions-cassandra-summit-eu-2014
Robert Stupp6.3K views
Mastering Java Bytecode - JAX.de 2012 by Anton Arhipov
Mastering Java Bytecode - JAX.de 2012Mastering Java Bytecode - JAX.de 2012
Mastering Java Bytecode - JAX.de 2012
Anton Arhipov2.6K views
Short intro to scala and the play framework by Felipe
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
Felipe 1.7K views

Viewers also liked

GitBucket: The perfect Github clone by Scala by
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scalatakezoe
26.7K views37 slides
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介 by
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介scalaconfjp
2.5K views38 slides
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ... by
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...scalaconfjp
3.3K views60 slides
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri) by
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)TIS Inc.
4.8K views25 slides
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫 by
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫gree_tech
10.8K views58 slides
sbt, past and future / sbt, 傾向と対策 by
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策scalaconfjp
4.5K views23 slides

Viewers also liked(15)

GitBucket: The perfect Github clone by Scala by takezoe
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scala
takezoe26.7K views
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介 by scalaconfjp
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介
scalaconfjp2.5K views
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ... by scalaconfjp
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...
scalaconfjp3.3K views
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri) by TIS Inc.
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
TIS Inc.4.8K views
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫 by gree_tech
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫
gree_tech10.8K views
sbt, past and future / sbt, 傾向と対策 by scalaconfjp
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策
scalaconfjp4.5K views
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo by Taro L. Saito
Weaving Dataflows with Silk - ScalaMatsuri 2014, TokyoWeaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Taro L. Saito3K views
芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜 by scalaconfjp
芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜
芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜
scalaconfjp5.5K views
Scala が支える医療系ウェブサービス #jissenscala by Kazuhiro Sera
Scala が支える医療系ウェブサービス #jissenscalaScala が支える医療系ウェブサービス #jissenscala
Scala が支える医療系ウェブサービス #jissenscala
Kazuhiro Sera30.3K views
Scala@SmartNews AdFrontend を Scala で書いた話 by Keiji Muraishi
Scala@SmartNews AdFrontend を Scala で書いた話Scala@SmartNews AdFrontend を Scala で書いた話
Scala@SmartNews AdFrontend を Scala で書いた話
Keiji Muraishi12.1K views
ビズリーチの新サービスをScalaで作ってみた 〜マイクロサービスの裏側 #jissenscala by takezoe
ビズリーチの新サービスをScalaで作ってみた 〜マイクロサービスの裏側 #jissenscalaビズリーチの新サービスをScalaで作ってみた 〜マイクロサービスの裏側 #jissenscala
ビズリーチの新サービスをScalaで作ってみた 〜マイクロサービスの裏側 #jissenscala
takezoe26.6K views
あなたのScalaを爆速にする7つの方法 by x1 ichi
あなたのScalaを爆速にする7つの方法あなたのScalaを爆速にする7つの方法
あなたのScalaを爆速にする7つの方法
x1 ichi9.1K views
Scala - The Simple Parts, SFScala presentation by Martin Odersky
Scala - The Simple Parts, SFScala presentationScala - The Simple Parts, SFScala presentation
Scala - The Simple Parts, SFScala presentation
Martin Odersky16.5K views
Scala Warrior and type-safe front-end development with Scala.js by takezoe
Scala Warrior and type-safe front-end development with Scala.jsScala Warrior and type-safe front-end development with Scala.js
Scala Warrior and type-safe front-end development with Scala.js
takezoe9.3K views

Similar to Solid And Sustainable Development in Scala

Wider than rails by
Wider than railsWider than rails
Wider than railsAlexey Nayden
1.8K views32 slides
Scala Frustrations by
Scala FrustrationsScala Frustrations
Scala Frustrationstakezoe
3.7K views36 slides
Beginning Scala with Skinny Framework #jjug_ccc by
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccKazuhiro Sera
2.4K views46 slides
Modern Front-End Development by
Modern Front-End DevelopmentModern Front-End Development
Modern Front-End Developmentmwrather
8K views30 slides
Scala Italy 2015 - Hands On ScalaJS by
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSAlberto Paro
1.2K views30 slides
Alberto Paro - Hands on Scala.js by
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsScala Italy
1.9K views30 slides

Similar to Solid And Sustainable Development in Scala(20)

Scala Frustrations by takezoe
Scala FrustrationsScala Frustrations
Scala Frustrations
takezoe3.7K views
Beginning Scala with Skinny Framework #jjug_ccc by Kazuhiro Sera
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_ccc
Kazuhiro Sera2.4K views
Modern Front-End Development by mwrather
Modern Front-End DevelopmentModern Front-End Development
Modern Front-End Development
mwrather8K views
Scala Italy 2015 - Hands On ScalaJS by Alberto Paro
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJS
Alberto Paro1.2K views
Alberto Paro - Hands on Scala.js by Scala Italy
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.js
Scala Italy1.9K views
Intro to node.js - Ran Mizrahi (27/8/2014) by Ran Mizrahi
Intro to node.js - Ran Mizrahi (27/8/2014)Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)
Ran Mizrahi1.1K views
Intro to node.js - Ran Mizrahi (28/8/14) by Ran Mizrahi
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi564 views
Typesafe stack - Scala, Akka and Play by Luka Zakrajšek
Typesafe stack - Scala, Akka and PlayTypesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and Play
Luka Zakrajšek3.3K views
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen... by Codemotion
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Codemotion808 views
Building web framework with Rack by sickill
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
sickill3.6K views
WebNet Conference 2012 - Designing complex applications using html5 and knock... by Fabio Franzini
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini1.6K views
SproutCore and the Future of Web Apps by Mike Subelsky
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky708 views
Day 2 - Intro to Rails by Barry Jones
Day 2 - Intro to RailsDay 2 - Intro to Rails
Day 2 - Intro to Rails
Barry Jones799 views
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09) by Daniel Bryant
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
Daniel Bryant3.2K views
Play Framework and Activator by Kevin Webber
Play Framework and ActivatorPlay Framework and Activator
Play Framework and Activator
Kevin Webber4.1K views
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14) by Evan Chan
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Evan Chan11.8K views
BP-6 Repository Customization Best Practices by Alfresco Software
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
Alfresco Software1.2K views

More from Kazuhiro Sera

All I learned while working on a Scala OSS project for over six years #ScalaM... by
All I learned while working on a Scala OSS project for over six years #ScalaM...All I learned while working on a Scala OSS project for over six years #ScalaM...
All I learned while working on a Scala OSS project for over six years #ScalaM...Kazuhiro Sera
488 views48 slides
Contributing to Scala OSS from East Asia #ScalaMatsuri by
 Contributing to Scala OSS from East Asia #ScalaMatsuri Contributing to Scala OSS from East Asia #ScalaMatsuri
Contributing to Scala OSS from East Asia #ScalaMatsuriKazuhiro Sera
10.9K views37 slides
Skinny Meetup Tokyo 2 日本語スライド by
Skinny Meetup Tokyo 2 日本語スライドSkinny Meetup Tokyo 2 日本語スライド
Skinny Meetup Tokyo 2 日本語スライドKazuhiro Sera
8.6K views24 slides
Skinny 2 Update by
Skinny 2 UpdateSkinny 2 Update
Skinny 2 UpdateKazuhiro Sera
7.9K views22 slides
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon by
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarconSeasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarconKazuhiro Sera
15.1K views46 slides
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek by
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageekJava エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageekKazuhiro Sera
17.1K views41 slides

More from Kazuhiro Sera(20)

All I learned while working on a Scala OSS project for over six years #ScalaM... by Kazuhiro Sera
All I learned while working on a Scala OSS project for over six years #ScalaM...All I learned while working on a Scala OSS project for over six years #ScalaM...
All I learned while working on a Scala OSS project for over six years #ScalaM...
Kazuhiro Sera488 views
Contributing to Scala OSS from East Asia #ScalaMatsuri by Kazuhiro Sera
 Contributing to Scala OSS from East Asia #ScalaMatsuri Contributing to Scala OSS from East Asia #ScalaMatsuri
Contributing to Scala OSS from East Asia #ScalaMatsuri
Kazuhiro Sera10.9K views
Skinny Meetup Tokyo 2 日本語スライド by Kazuhiro Sera
Skinny Meetup Tokyo 2 日本語スライドSkinny Meetup Tokyo 2 日本語スライド
Skinny Meetup Tokyo 2 日本語スライド
Kazuhiro Sera8.6K views
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon by Kazuhiro Sera
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarconSeasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Kazuhiro Sera15.1K views
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek by Kazuhiro Sera
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageekJava エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Kazuhiro Sera17.1K views
Future on Servlet #scala_ks by Kazuhiro Sera
Future on Servlet #scala_ksFuture on Servlet #scala_ks
Future on Servlet #scala_ks
Kazuhiro Sera1.1K views
Servlet と Future の関わり方 #scala_ks by Kazuhiro Sera
Servlet と Future の関わり方 #scala_ksServlet と Future の関わり方 #scala_ks
Servlet と Future の関わり方 #scala_ks
Kazuhiro Sera7.2K views
マイクロサービス運用の所感 #m3dev by Kazuhiro Sera
マイクロサービス運用の所感 #m3devマイクロサービス運用の所感 #m3dev
マイクロサービス運用の所感 #m3dev
Kazuhiro Sera33.3K views
Scala on Rails #rakutentech by Kazuhiro Sera
Scala on Rails #rakutentechScala on Rails #rakutentech
Scala on Rails #rakutentech
Kazuhiro Sera4.6K views
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24 by Kazuhiro Sera
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
Kazuhiro Sera23.3K views
Skinny Framework 1.0.0 by Kazuhiro Sera
Skinny Framework 1.0.0Skinny Framework 1.0.0
Skinny Framework 1.0.0
Kazuhiro Sera3.8K views
Skinny Framework Progress Situation by Kazuhiro Sera
Skinny Framework Progress SituationSkinny Framework Progress Situation
Skinny Framework Progress Situation
Kazuhiro Sera1.2K views
Skinny Framework 進捗どうですか? #fud_scala by Kazuhiro Sera
Skinny Framework 進捗どうですか? #fud_scalaSkinny Framework 進捗どうですか? #fud_scala
Skinny Framework 進捗どうですか? #fud_scala
Kazuhiro Sera5.1K views
テストの運用について #m3dev by Kazuhiro Sera
テストの運用について #m3devテストの運用について #m3dev
テストの運用について #m3dev
Kazuhiro Sera3.9K views
めんどくさくない Scala #kwkni_scala by Kazuhiro Sera
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
Kazuhiro Sera18.1K views
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech by Kazuhiro Sera
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech
Kazuhiro Sera3.1K views
Kabukiza.tech 1 LT - ScalikeJDBC-Async & Skinny Framework #kbkz_tech by Kazuhiro Sera
Kabukiza.tech 1 LT - ScalikeJDBC-Async & Skinny Framework #kbkz_techKabukiza.tech 1 LT - ScalikeJDBC-Async & Skinny Framework #kbkz_tech
Kabukiza.tech 1 LT - ScalikeJDBC-Async & Skinny Framework #kbkz_tech
Kazuhiro Sera2.4K views
テストを書くのが嫌いな君へ #m3dev by Kazuhiro Sera
テストを書くのが嫌いな君へ #m3devテストを書くのが嫌いな君へ #m3dev
テストを書くのが嫌いな君へ #m3dev
Kazuhiro Sera7.3K views
Skinny Controllers, Skinny Models by Kazuhiro Sera
Skinny Controllers, Skinny ModelsSkinny Controllers, Skinny Models
Skinny Controllers, Skinny Models
Kazuhiro Sera5.5K views

Solid And Sustainable Development in Scala

  • 1. Solid and Sustainable Development in Scala Kazuhiro Sera @seratch ScalikeJDBC / Skinny Framework Founder & Lead Developer
  • 2. Ask Me Later! • 3 mags for questioners at the end of this session! Don’t miss it! 2
  • 3. Who Am I • Kazuhiro Sera • @seratch on Twitter/GitHub • Scala enthusiast since 2010 • ScalikeJDBC, Skinny Framework, AWScala founder & project lead • A web developer at M3, Inc (We’re a Gold Sponsor)
  • 5. ScalikeJDBC • scalikejdbc.org • “Scala-like JDBC” • Provides Scala-ish APIs • Started as a better querulous / Anorm • “Just write SQL and get things done” • QueryDSL for smoothness & type-safety • Stable enough: lots of companies already use it in production
  • 6. Dependencies // build.sbt or project/Build.scala! ! scalaVersion := “2.11.2” // or “2.10.4”! ! libraryDependencies ++= Seq(! “org.scalikejdbc” %% “scalikejdbc” % “2.1.1”,! “com.h2database” % “h2” % “1.4.181”,! “ch.qos.logback” % “logback-classic” % “1.1.2”! )
  • 7. Basic Usage import scalikejdbc._! ! ConnectionPool.singleton(! “jdbc:h2:mem:matsuri”, ! “user”, “secret”)! SQL statement! (PreparedStatement) ! DB autoCommit { implicit session =>! Side effect ! with DB connection sql”create table attendee (name varchar(32))”.execute.apply()! val name = “seratch”! sql”insert into attendee (name) values ($name)”.update.apply()! }! ! val names: Seq[String] = DB readOnly { implicit s =>! sql”select name from attendee”! .map(_.string(“name”)).list.apply()! } execute/update! (JDBC operation) Extractor
  • 8. QueryDSL import scalikejdbc._! case class Attendee(name: String)! object Attendee extends SQLSyntaxSupport[Attendee] {! def apply(rs: WrappedResultSet, a: ResultName[Attendee]) = ! new Attendee(rs.get(a.name)) }! ! implicit val session = AutoSession! ! ! val a = Attendee.syntax(“a”)! val seratch: Option[Attendee] = withSQL {! QueryDSL! (Mostly SQL) Actual SQL Query select.from(Attendee as a).where.eq(a.name, “seratch”)! }.map(rs => new Attendee(rs, a)).single.apply()! ! // select a.name as n_on_a from attendee a where a.name = ?
  • 9. Skinny Framework • skinny-framework.org • “Scala on Rails” • For Rails / Play1 lovers • 1.0.0 was out on 28th March • Already several experiences in production • Full-stack features: Web infrastructure, Scaffold generator, ORM, DB migration, JSON stuff, HTTP client, Mail sender, Job workers, Assets controller, etc..
  • 10. Boot in 2 minutes ! // install skinny command! brew tap skinny-framework/alt! brew install skinny! ! // create app and start! skinny new myapp! cd myapp! skinny run! ! // access localhost:8080 from your browser!
  • 11. Model (DAO) import skinny.orm._! Entity import scalikejdbc._! ! case class User(id: Long, name: Option[String])! ! // companion: data mapper! object User extends SkinnyCRUDMapper[User] {! def defaultAlias = createAlias(“u”)! def extract(rs: WrappedResultSet, u: ResultName[User])! = autoConstruct(rs, u) }! CRUD Mapper Object! ! (No need to be companion) User.findById(123)! User.count()! User.createWithAttributes(‘name -> “Alice”)! User.updateById(123).withAttributes(‘name -> “Bob”)! User.deleteBy(sqls.eq(u.name, “Bob”)) Smooth APIs
  • 12. Controller + Route package controller! class UsersController extends ApplicationController {! def showUsers = {! set(“users”, User.findAll())! render(“/users/index”) } }! ! // Routings! object Controllers {! Set value in request scope! (Visible in views) Expects “src/main/webapp/! WEB-INF/views/users/index.html.ssp” val users = new UsersController with Routes {! get(“/users/”)(showUsers).as(‘showUsers) }! def mount(ctx: ServletContext): Unit = {! users.mount(ctx)! } }
  • 13. View Template // src/main/webapp/WEB-INF/views/users/index.html.ssp! ! <%@val users: Seq[User] %>! ! <table class=“table”>! #for (user <- users)! <tr>! <td>${user.id}</td>! <td>${user.name}</td>! </tr>! #end! </table> import from request scope Loop, if/else syntax! in Scalate
  • 14. Web Development • Interactive feedback loop is most important especially when changing UI • Actually Scala compilation is so slow that waiting view templates compilation makes developers much stressed • Skinny doesn’t compile all the view templates when developing (unlike Twirl)
  • 15. My Good Parts for Solid and Safe Development
  • 16. My Good Parts •Simplified Class-based OOP And Immutable Data Structure •Working On Problems Without Overkill Abstraction •Writing Tests Without Question •Keep Infrastructure Lightweight •No Surprises For Newcomer
  • 17. Simplified Class-based OOP And Immutable Data Structure
  • 18. Class-based OOP • Already so popular (Java, Ruby, Python ..) • Old style is friendly with mutability (e.g. setters, bang methods), but that’s not a prerequisite • OOP can be more solid and safer by keeping immutability and avoiding inheritance anti-patterns
  • 19. Scala or Java 8? • Scala case class is simpler than Java beans with (great) Lombok • Scala high-order functions are simpler than Java 8 Stream API • Immutability is well-treated in Scala • Fairness: Java decisively beats Scala in comparison with compilation speed..
  • 20. Immutability • Do away with mutable states • Re-assignment? No way! Don’t use `var` • Immutability makes your apps not only scalable but also more solid • When you modify a case class, call #copy() and return new state instead of using setters for mutability inside
  • 21. Immutable Entity // entity with behaviors! case class User(id: Long, name: Option[String])! extends SkinnyRecord[User] {! override def skinnyCRUDMapper = User }! // data mapper! object User extends SkinnyCRUDMapper[User] {! override def defaultAlias = createAlias(“u”)! override def extract(rs: WrappedResultSet, u: ResultName[User])! = autoConstruct(rs, u) }! ! val noNames: Seq[User] = User.where(‘name -> “”).apply()! val anons: Seq[User] = noNames.map { user => ! user.copy(name = “Anonymous”).save()! } Both of “noNames” and “anons” are immutable
  • 22. Trait Chaos • Mixing traits can show you terrible chaos • We should have self-discipline • Prefer `override` modifier to detect API changes when mixing many traits • Collect the same sort of traits and place them in same place to avoid code duplication or unwanted complexity
  • 23. Web Controller package controller! class MainController extends ApplicationController ! with concern.TimeLogging {! def index = logElapsedTime { render(“/main/index”) }! }! ! // for controllers! package controller.concern! trait TimeLogging { self: SkinnyController with Logging =>! The “concern” just follows Rails style. Anyway, naming should be simple and! easy-to-understand for anyone def millis: Long = System.currentTimeMillis ! def logElapsedTime[A](action: => A): A = {! val before = millis! val result = action! logger.debug(“Elapsed time: ${millis - before} millis”)! result }! }
  • 24. Coding Style Tips • Use sbt-scalariform without question (similar: go-lang’s fmt) • Don’t toss similar classes or traits into single scala file except `sealed` pattern • Don’t place classes under different package directory (although it’s possible) • Do you really need cake pattern? • Prefer eloquent method signature than explaining a lot in scaladocs
  • 25. Working On Problems Without Overkill Abstraction
  • 26. The Real As-Is • Abstraction often improves things, but that’s not always the best way to solve real-world problems • I/O issue is a typical case that we should comprehend problems as-is • Database access / SQL is not a collection but just an external I/O operation • Overkill abstraction makes your code difficult to maintain for other developers
  • 27. Don’t Hide the SQL • “You don’t need another DSL to access relational databases” - Anorm • You must recognize what is working effectively in the SQL layer • Utility to write DAO easily is fine but hiding SQL is not good • Need to grab the cause from raw queries when dealing with troubles (comfortable logging also can help)
  • 28. SQL Ops As-Is // A programmer belongs to a company and has several skills! ! implicit val session = AutoSession! ! val p: Option[Programmer] = withSQL {! I believe everybody can understand this code select.from(Programmer as p)! .leftJoin(Company as c).on(p.companyId, c.id)! .leftJoin(ProgrammerSkill as ps).on(ps.programmerId, p.id)! .leftJoin(Skill as s).on(ps.skillId, s.id)! .where.eq(p.id, 123).and.isNull(p.deletedAt)! }! .one(rs => Programmer(rs, p, c))! Extracts one-to-many .toMany(rs => Skill.opt(rs, s))! relationships here .map { (programmer, skills) => programmer.copy(skills = skills) }! .single! .apply()
  • 29. Skinny ORM • ORM built on ScalikeJDBC • Highly inspired by Rails ActiveRecord • SQL queries for CRUD apps are common enough, so it’s reasonable to avoid writing mostly same code everywhere • Skinny ORM doesn't prevent you from using ScaikeJDBC APIs directly • A part of Skinny Framework but you can use it in Play apps too
  • 30. Dependencies // build.sbt or project/Build.scala! ! scalaVersion := “2.11.2” // or “2.10.4”! ! libraryDependencies ++= Seq(! //“org.scalikejdbc” %% “scalikejdbc” % “2.1.1”,! “org.skinny-framework” %% “skinny-orm” % “1.3.1”,! “com.h2database” % “h2” % “1.4.181”,! “ch.qos.logback” % “logback-classic” % “1.1.2”! )
  • 31. Mappers // entities! case class Company(id: Long, name: String)! case class Employee(id: Long, name: String,! companyId: Long, company: Option[Company])! ! // mappers! object Company extends SkinnyCRUDMapper[Company] {! def extract(rs: WrappedResultSet, rn: ResultName[Company]) =! autoConstruct(rs, rn) }! object Employee extends SkinnyCRUDMapper[Employee] {! def extract(rs: WrappedResultSet, rn: ResultName[Employee]) =! autoConstruct(rs, rn, “company”)! // simple association definition! lazy val companyRef = belongsTo[Company](! Company, (e, c) => e.copy(company = c)) }
  • 32. Reasonable? Right, these CRUD operations are not SQL-ish. However, I believe they’re reasonable because these patterns are already common enough. ! ! val companyId = Company.createWithAttributes(‘name -> “Sun”)! val empId = Employee.createWithAttributes(! ‘name -> “Alice”, ‘companyId -> companyId)! ! val emp: Option[Employee] = Employee.findById(empId)! val empWithCompany: Option[Employee] = ! Employee.joins(companyRef).findById(123)! ! Company.updateById(companyId).withAttributes(‘name -> “Oracle”)! ! val e = Employee.defaultAlias! Employee.deleteBy(sqls.eq(e.id, empId))! Using ScalikeJBDC API! Company.deleteById(companyId) is also possible
  • 34. Not Only Compiler • It’s true that compiler helps you by detecting mistakes in coding • Writing tests is a reasonable way to verify your code meets requirements / specifications as expected • You can’t skip automated tests even if your apps are written in Scala
  • 35. scoverage • At this time, the only option available for us is scoverage (SCCT inheritor) • Add the dependency into your projects right now if you don’t use it yet
  • 37. Avoid SBT Hacks • sbt is not so easy for Scala newbies, upgrading sbt is all the more so • Play depends on sbt version (e.g. Play 2.1 w/ sbt 0.12), upgrading Play is about not only Play API changes but sbt things • Your own sbt plugins/hacks make your projects difficult to maintain for a long period and involve others • Don’t try to do everything there
  • 38. Skinny TaskRunner • Just want a simple and “rake”-like task runner (no sbt plugin) • Simplistic but pragmatic idea: “mainClass” of “task” sbt project can be dispatcher of task runner system • Tasks are written in Scala (no sbt plugin) • Not only writing code but upgrading scala/sbt version become pretty easy
  • 39. Tasks // sbt settings! // mainClass := Some("TaskRunner")! ! // task/src/main/scala/TaskRunner.scala! object TaskRunner extends skinny.task.TaskLauncher {! register("assets:precompile", (params) => {! val buildDir = params.headOption.getOrElse(“build")! // AssetsPrecompileTask is a Scala object! skinny.task.AssetsPrecompileTask.main(Array(buildDir))! })! }! Pure Scala function! ! // skinny task:run assets:precompile [dir] task name mainClass as the dispatcher
  • 40. Use Only Essentials • The same issue as Ruby gems, what’s worse, Scala’s eco-system is still so smaller than Ruby’s one • Binary incompatibility makes existing libraries outdated every Scala major version release • Are you really ready to fork them? • Using Java assets (e.g. commons) internally is also worth thinking about
  • 41. No Surprises for Newcomer
  • 42. Can Feel Welcome? • Is joining your Scala projects easy? Can newcomer understand overview at once? • Don’t stick to doing on the sbt, don’t disfavor using other tools (e.g. Grunt) • Well-known style (e.g. Rails style) is preferred for collaborative works • Is asynchronosity really required now? • Indeed, your DSL is very simple but easy to modify them (for others)?
  • 43. Newcomers may not know Scala well. Attract them to Scala! (Don’t scare them)
  • 44. AMA! #ScalaMatsuri2 • Unconference tomorrow • “Ask Me Anything” • ScalikeJDBC • Skinny Framework • AWScala • Anything else!
  • 48. Thanks • Amazing “Maturi Urakata” (the conference volunteer staff) • Great invited speakers • You all here!