SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
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!
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 is 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 my app! 
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 
“anions” 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 
Play API but sbt things • Your own sbt plugins/hacks makes 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!

Mais conteúdo relacionado

Mais procurados

Scala overview
Scala overviewScala overview
Scala overview
Steve Min
 
An Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional ParadigmsAn Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional Paradigms
Miles Sabin
 

Mais procurados (17)

All about scala
All about scalaAll about scala
All about scala
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
 
Scala overview
Scala overviewScala overview
Scala overview
 
Scala
ScalaScala
Scala
 
Scala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud FoundryScala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud Foundry
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scala
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to Scala
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Scala on Android
Scala on AndroidScala on Android
Scala on Android
 
An Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional ParadigmsAn Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional Paradigms
 

Destaque (6)

2.3 implicits
2.3 implicits2.3 implicits
2.3 implicits
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
2.6 summary day-2
2.6 summary day-22.6 summary day-2
2.6 summary day-2
 
Kicking Butt on Concurrent Enterprise Application with Scala
Kicking Butt on Concurrent Enterprise Application with ScalaKicking Butt on Concurrent Enterprise Application with Scala
Kicking Butt on Concurrent Enterprise Application with Scala
 
BCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersBCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java Developers
 
2.5 the quiz-game
2.5 the quiz-game2.5 the quiz-game
2.5 the quiz-game
 

Semelhante a Solid and Sustainable Development in Scala

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)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi
 
Typesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and PlayTypesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and Play
Luka Zakrajšek
 
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...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on Rails
Avi Kedar
 

Semelhante a Solid and Sustainable Development in Scala (20)

Wider than rails
Wider than railsWider than rails
Wider than rails
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
 
Beginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_ccc
 
Modern Front-End Development
Modern Front-End DevelopmentModern Front-End Development
Modern Front-End Development
 
Alberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.js
 
Scala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJS
 
Scala active record
Scala active recordScala active record
Scala active record
 
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)
Intro to node.js - Ran Mizrahi (27/8/2014)
 
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)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Play framework
Play frameworkPlay framework
Play framework
 
Typesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and PlayTypesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and Play
 
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...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
 
Day 2 - Intro to Rails
Day 2 - Intro to RailsDay 2 - Intro to Rails
Day 2 - Intro to Rails
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
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...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on Rails
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
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)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
 
Play Framework and Activator
Play Framework and ActivatorPlay Framework and Activator
Play Framework and Activator
 

Mais de scalaconfjp

Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメントScalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
scalaconfjp
 

Mais de scalaconfjp (20)

脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
 
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
 
GraalVM Overview Compact version
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact version
 
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
 
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
 
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan GoyeauScala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
 
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
 
Scala ♥ Graal by Flavio Brasil
Scala ♥ Graal by Flavio BrasilScala ♥ Graal by Flavio Brasil
Scala ♥ Graal by Flavio Brasil
 
Introduction to GraphQL in Scala
Introduction to GraphQL in ScalaIntroduction to GraphQL in Scala
Introduction to GraphQL in Scala
 
Safety Beyond Types
Safety Beyond TypesSafety Beyond Types
Safety Beyond Types
 
Reactive Kafka with Akka Streams
Reactive Kafka with Akka StreamsReactive Kafka with Akka Streams
Reactive Kafka with Akka Streams
 
Reactive microservices with play and akka
Reactive microservices with play and akkaReactive microservices with play and akka
Reactive microservices with play and akka
 
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメントScalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
 
DWANGO by ドワンゴ
DWANGO by ドワンゴDWANGO by ドワンゴ
DWANGO by ドワンゴ
 
OCTOPARTS by M3, Inc.
OCTOPARTS by M3, Inc.OCTOPARTS by M3, Inc.
OCTOPARTS by M3, Inc.
 
Try using Aeromock by Marverick, Inc.
Try using Aeromock by Marverick, Inc.Try using Aeromock by Marverick, Inc.
Try using Aeromock by Marverick, Inc.
 
統計をとって高速化する
Scala開発 by CyberZ,Inc.
統計をとって高速化する
Scala開発 by CyberZ,Inc.統計をとって高速化する
Scala開発 by CyberZ,Inc.
統計をとって高速化する
Scala開発 by CyberZ,Inc.
 
Short Introduction of Implicit Conversion by TIS, Inc.
Short Introduction of Implicit Conversion by TIS, Inc.Short Introduction of Implicit Conversion by TIS, Inc.
Short Introduction of Implicit Conversion by TIS, Inc.
 
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
 
sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策
 

Último

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Último (20)

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 

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!
  • 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 is 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 my app! 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 “anions” 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 Play API but sbt things • Your own sbt plugins/hacks makes 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!