Scala සමඟ Spring Boot: අලුත් ලෝකයක දොරටුවක් (SC Guide)

Spring Boot with Scala Integration: අලුත් ලෝකයක දොරටුවක්!
මචන්ලා, වැඩ දේවල් කොහොමද? ඔයාලා හැමෝම සැපට ඉන්නවා කියලා හිතනවා! අද අපි කතා කරන්නේ ලංකාවේ Software Engineering ක්ෂේත්රයේ ගොඩක් දෙනෙක්ට වැදගත් වෙන, ඒ වගේම අපේ වැඩ කටයුතු තවත් අලුත් මට්ටමකට ගෙනියන්න පුළුවන් පට්ට Topic එකක් ගැන. ඒ තමයි Spring Boot කියන ජනප්රිය Framework එකයි, Scala කියන බලගතු Programming Language එකයි එකතු කරලා වැඩ කරන්නේ කොහොමද කියන එක.
දැන් ඔයාලා හිතනවා ඇති, 'අනේ යකෝ, Spring Boot කියන්නේ Java වලට නේ, Scala මේකට මොකටද?' කියලා. ඔව්, ඇත්තටම Spring Boot කියන්නේ Java ecosystem එකේ ඉන්න කෙනෙක්. ඒත්, Scala කියන්නෙත් JVM (Java Virtual Machine) එක මත දුවන Language එකක්. ඉතින්, මේ දෙන්නාව එකට වැඩ කරවන්න බැරි හේතුවක් නැහැ. ඒ වගේම, මේ දෙන්නා එකතු වුණාම අපිට හිතාගන්න බැරි තරම් බලගතු Solutions හදන්න පුළුවන්.
මේ Blog Post එකෙන් අපි බලමු Spring Boot සහ Scala එකට පාවිච්චි කරන්නේ ඇයි කියලා, කොහොමද අපේ Environment එක Set කරගන්නේ කියලා, ඊට පස්සේ සරල Scala Spring Boot Controller එකක් හදලා ඒක වැඩ කරන විදිහ බලමු. අන්තිමට, තව පොඩ්ඩක් ගැඹුරට මේකේ තියෙන Features ගැනත් කතා කරමු. එහෙනම්, අපි පටන් ගමු!
Spring Boot සහ Scala - ඇයි මේ මිශ්රණය?
මුලින්ම බලමු මේ දෙක වෙන වෙනම මොනවද කියලයි, ඇයි මේ දෙන්නා එකට හොඳට ගැලපෙන්නේ කියලයි.
Spring Boot - කම්මැලියන්ගේ යාළුවා!
Spring Boot කියන්නේ Java Developersලාට ඉක්මනට, ලේසියෙන් Standalone, Production-ready Spring Applications හදන්න පුළුවන් Framework එකක්. මේකේ ප්රධානම වාසි ටිකක් තමයි:
- Rapid Development: ඉක්මනට Applications හදන්න පුළුවන්. Boilerplate code ගොඩක් අඩුයි.
- Auto-configuration: ගොඩක් දේවල් මේකේ Automatically Configure වෙනවා. අපිට අතින් ගොඩක් Configure කරන්න ඕන වෙන්නේ නැහැ.
- Embedded Servers: Tomcat, Jetty වගේ Servers මේකේ Built-in එනවා. වෙනම Deploy කරන්න ඕන වෙන්නේ නැහැ.
- Production-ready Features: Health checks, Metrics, Externalized configuration වගේ Production වලට ඕන කරන Features මේකේ තියෙනවා.
ඔය ටික නිසා Spring Boot කියන්නේ Microservices හදන්න, REST APIs හදන්න කදිම Choice එකක්.
Scala - බලගතු බහුකාර්යයා!
Scala කියන්නේ JVM මත දුවන Multi-paradigm Programming Language එකක්. ඒ කියන්නේ මේකේ Functional Programming (FP) සහ Object-Oriented Programming (OOP) දෙකම එකට තියෙනවා. Scala වල ප්රධාන වාසි ටිකක් මෙන්න:
- Conciseness: Java වලට වඩා ගොඩක් අඩු Code Lines වලින් වැඩේ කරගන්න පුළුවන්.
- Functional Programming: Immutable data, Higher-order functions වගේ FP Concepts නිසා Robust, Concurrent Applications හදන්න ලේසියි.
- Strong Static Typing: Compile-time එකේදීම ගොඩක් Errors අල්ලගන්න පුළුවන්.
- Concurrency: Akka Framework එක වගේ දේවල් එක්ක Concurrency Management එක Super.
- JVM Compatibility: Java Libraries, Frameworks එක්ක Full Compatibility එකක් තියෙනවා.
දෙන්නා එකට එකතු වුණාම?
දැන් හිතන්න, Spring Boot වල වේගයයි, Scala වල බලයයි, FP හැකියාවයි එකතු වුණාම මොනවගේ Application එකක් හදන්න පුළුවන්ද කියලා. නියමයි නේද? මේකෙන් අපිට ලැබෙන වාසි ටිකක් තමයි:
- වැඩි දියුණු කළ Productivity: Scala වල Conciseness සහ Spring Boot වල Auto-configuration නිසා වේගයෙන් Development කරන්න පුළුවන්.
- Functional Programming වල වාසි: විශේෂයෙන් Concurrency වැඩි Microservices, Data Processing Applications වලට Scala වල FP හැකියාව ලොකු වාසියක්.
- Type Safety: Scala වල Strong Type System එක නිසා Runtime Errors ගොඩක් අඩු වෙනවා.
- පවතින Spring Ecosystem එක භාවිතය: Spring Security, Spring Data JPA වගේ Spring Ecosystem එකේ තියෙන හැම Library එකක්ම Scala එක්ක පාවිච්චි කරන්න පුළුවන්.
ඉතින්, මේ Combination එක විශේෂයෙන්ම Performance ඕන කරන, Business Logic එක සංකීර්ණ Microservices වලට වගේම Data intensive Applications වලටත් Super Choice එකක්.
සකසාගනිමු අපේ පරිසරය (Setting up Our Environment)
Spring Boot Application එකක් Scala වලින් හදන්න කලින් අපිට ඕන කරන Tools ටික Install කරගමු.
පූර්ව අවශ්යතා (Prerequisites)
- Java Development Kit (JDK): 8 හෝ ඊට ඉහළ Version එකක්.
- SBT (Scala Build Tool): Scala Project Build කරන්න, Dependencies Manage කරන්න මේක ඕන වෙනවා. SBT Website එකට ගිහින් Download කරගන්න.
- IDE: IntelliJ IDEA (Community Edition හෝ Ultimate) එකේ Scala Plugin එක Install කරගන්න. මේකෙන් Scala Project Management එක ලේසි වෙනවා.
Project එකක් පටන් ගමු!
අපිට Project එක පටන් ගන්න ක්රම දෙකක් තියෙනවා. එකක් තමයි SBT Template එකක් පාවිච්චි කරන එක, අනිත් එක Manual Setup කරන එක.
ක්රමය 1: SBT Template එකක් භාවිතයෙන් (Using an SBT Template)
SBT වලට Spring Boot Giter8 Template එකක් තියෙනවා. මේකෙන් ලේසියෙන්ම Project එකක් Generate කරගන්න පුළුවන්.
sbt new scala/spring-boot.g8
මේ Command එක දුන්නම Project Name එක වගේ දේවල් අහනවා. ඒ ටික දුන්නම ඔයාලගේ Project එක Automatically Generate වෙයි.
ක්රමය 2: Manual Setup (වැඩි පාලනයක් සඳහා)
මේක තමයි මම Recommend කරන්නේ, මොකද ඔයාලට Project Structure එක ගැන හොඳ අවබෝධයක් ලැබෙන නිසා.
scala3Version
: අපි පාවිච්චි කරන Scala Version එක.root
: මේක තමයි අපේ Project Definition එක.name
,version
,scalaVersion
: Project එකේ නම, Version එක, Scala Version එක.libraryDependencies
: මෙතන තමයි අපිට ඕන කරන Libraries ටික දාන්නේ.spring-boot-starter-web
එක Web Application එකකට අත්යවශ්යයි.spring-boot-starter-test
එක Testing වලට.assembly / mainClass
,assembly / assemblyJarName
: මේවා SBT Assembly Plugin එකට අදාළයි. මේකෙන් පුළුවන් අපේ Application එකේ සියලුම Dependencies එකට එකතු කරලා Single "Fat JAR" එකක් හදන්න. මේක Production වලට Deploy කරන්න ගොඩක් ලේසියි.assembly / assemblyMergeStrategy
: මේක වැදගත් වෙන්නේ Libraries වල තියෙන සමහර Files Merge කරනකොට Conficts එන එක වලක්වන්න. විශේෂයෙන්spring.factories
File එක Spring Boot වලට වැදගත්.
Project Structure එක හදන්න:Spring Boot Application එකේ Source Code තියෙන්න ඕන Standard Maven/Gradle Structure එකට සමානව. Scala Project එකක් නිසා src/main/scala
සහ src/test/scala
කියලා Folder හදන්න ඕන.
my-scala-spring-boot-app/
├── build.sbt
└── src/
├── main/
│ └── scala/
│ └── com/
│ └── example/
│ └── demo/
│ └── Application.scala
└── test/
└── scala/
└── com/
└── example/
└── demo/
└── HelloWorldControllerSpec.scala
මේ Structure එක හැදුවට පස්සේ අපි බලමු කොහොමද Controller එකක් හදන්නේ කියලා.
build.sbt
File එක හදන්න:Project Root එකේ build.sbt
කියන File එක හදලා මේ Content එක දාන්න.
val scala3Version = "3.4.2" // ඔයාලට ඕන Scala Version එක දාන්න
lazy val root = project
.in(file("."))
.settings(
name := "my-scala-spring-boot-app",
version := "0.1.0-SNAPSHOT",
scalaVersion := scala3Version,
libraryDependencies ++= Seq(
// Spring Boot Starters
"org.springframework.boot" % "spring-boot-starter-web" % "3.2.5", // Spring Boot Version එක දාන්න
"org.springframework.boot" % "spring-boot-starter-test" % "3.2.5" % Test,
// Scala specific dependencies for Spring Boot
"org.scala-lang.modules" %% "scala-collection-compat" % "2.12.0", // Spring Boot 3+ සඳහා වැදගත් විය හැක
// Scala Test Framework
"org.scalatest" %% "scalatest" % "3.2.18" % Test,
"org.scalatestplus" %% "mockito-4-12" % "3.2.17.0" % Test // Mockito සඳහා
),
// SBT assembly plugin configuration (for creating a fat JAR)
assembly / mainClass := Some("com.example.demo.Application"), // ඔයාලගේ Main Class එක දාන්න
assembly / assemblyJarName := "my-scala-spring-boot-app.jar",
assembly / assemblyMergeStrategy := {
case PathList("META-INF", "spring.factories") => MergeStrategy.concat
case x => MergeStrategy.defaultMerge
}
)
addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.3" cross CrossVersion.full)
විස්තරය:
Project Folder එකක් හදන්න:
mkdir my-scala-spring-boot-app
cd my-scala-spring-boot-app
සරල Scala Spring Boot Controller එකක් (A Simple Scala Spring Boot Controller)
දැන් අපි Project එක Setup කරගත්තා. අපි මුලින්ම හදමු අපේ Main Spring Boot Application Class එකයි, ඊට පස්සේ සරල HelloWorld Controller එකකුයි.
Application.scala File එක
src/main/scala/com/example/demo/Application.scala
File එකේ මේ Code එක දාන්න:
package com.example.demo
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.web.bind.annotation.{GetMapping, RestController}
import org.springframework.stereotype.Service
import org.springframework.beans.factory.annotation.Autowired
// Spring Boot Application එක ආරම්භ කරන Main Class එක.
// @SpringBootApplication කියන්නේ @Configuration, @EnableAutoConfiguration, @ComponentScan වල එකතුවක්.
@SpringBootApplication
class Application
// Scala හි App trait එක භාවිතයෙන් Main Method එක නිර්මාණය කිරීම.
// මෙය Java වල public static void main(String[] args) {} හා සමානයි.
object Application extends App {
// Spring Boot Application එක Run කරනවා.
SpringApplication.run(classOf[Application])
println("Spring Boot Application එක සාර්ථකව ආරම්භ විය!")
}
// මෙහිදී අපි සරල Service එකක් නිර්මාණය කරමු.
// @Service annotation එක මගින් Spring Context එකට මේ class එක Component එකක් ලෙස register කරනවා.
@Service
class GreetingService {
def getGreeting(name: String): String = {
s"සුභ දවසක්, $name! Scala Spring Boot වලින් ඔයාව සාදරයෙන් පිළිගන්නවා."
}
}
// RESTful Web Service එකක් ලෙස ක්රියා කරන Controller එක.
// @RestController annotation එක @Controller සහ @ResponseBody වල එකතුවක්.
@RestController
class HelloWorldController {
// Spring Dependency Injection භාවිතයෙන් GreetingService එක Inject කරනවා.
// Scala වලදී val field එකක් මත @Autowired දාන්න පුළුවන්.
@Autowired
private val greetingService: GreetingService = null // null initialize කිරීම Type system එකට අවශ්යයි
// HTTP GET requests /hello path එකට map කරනවා.
@GetMapping("/hello")
def sayHello(): String = {
"ආයුබෝවන්, Scala සහ Spring Boot ලෝකයට!"
}
// HTTP GET requests /greet/{name} path එකට map කරනවා.
// PathVariable එකක් ලෙස name parameter එක ගන්නවා.
@GetMapping("/greet/{name}")
def greetName(name: String): String = {
// Service එකේ method එකක් call කරනවා.
greetingService.getGreeting(name)
}
// Optional values හැසිරවීම සඳහා උදාහරණයක්.
// Spring 6.1+ සිට Scala Option type එක @RequestParam වලට support කරනවා.
@GetMapping("/search")
def search(@org.springframework.web.bind.annotation.RequestParam query: Option[String]): String = {
query match {
case Some(q) => s"ඔබ සෙව්වේ: $q"
case None => "සෙවීමට කිසිවක් ඇතුලත් කර නොමැත."
}
}
}
Code එක විස්තර කිරීම
@SpringBootApplication class Application
: මේක තමයි අපේ Spring Boot Application එකේ Entry Point එක. Java වල වගේම Scala වලත් Class එකක් විදිහට මේක නිර්මාණය කරලා තියෙනවා.object Application extends App
: Scala වලදී Main Method එකක් නිර්මාණය කරන්නApp
trait එක පාවිච්චි කරන්න පුළුවන්. මේක Java වලpublic static void main(String[] args)
එකට සමානයි. මේක ඇතුලේ අපිSpringApplication.run(classOf[Application])
කියලා Spring Boot Application එක ආරම්භ කරනවා.@RestController class HelloWorldController
: මේක තමයි අපේ Web Controller එක.@RestController
Annotation එකෙන් Spring Boot එකට කියනවා මේ Class එක RESTful Service එකක් විදිහට Request හසුරුවනවා කියලා.@Autowired private val greetingService: GreetingService
: මෙතනදී අපිGreetingService
එක Controller එකට Inject කරනවා. Spring Framework එකේ Dependency Injection (DI) එක Scala වලත් හොඳට වැඩ කරනවා. Scala වලදීval
Field එකක් මත@Autowired
දාන්න පුළුවන්.@GetMapping("/hello") def sayHello(): String
: මේ Method එක HTTP GET Request එකක්/hello
කියන Path එකට එනකොට execute වෙනවා. මේකෙන් Return කරන්නේ සරල String එකක්.@GetMapping("/greet/{name}") def greetName(name: String): String
: මේ Method එක HTTP GET Request එකක්/greet/<නමක්>
වගේ Path එකකට එනකොට execute වෙනවා.{name}
කියන එක Path Variable එකක් විදිහට අරගෙනname
Parameter එකට දෙනවා.@GetMapping("/search") def search(@RequestParam query: Option[String]): String
: මේක නියම Example එකක්. Spring Boot 6.1+ වගේ Latest versions වලින් Scala වලOption
Type එක කෙලින්ම Support කරනවා. ඒ කියන්නේ Request Parameter එකක් Optional නම් (තියෙන්නත් පුළුවන්, නැති වෙන්නත් පුළුවන්) අපිට ScalaOption
එකක් විදිහට අරගන්න පුළුවන්.
Application එක Run කරමු!
දැන් අපි හදපු Application එක Run කරලා බලමු.
- Browser එකෙන් හෝ cURL වලින් Test කරමු:
Fat JAR එකක් හදලා Run කරනවා නම්:build.sbt
එකේ assembly
Plugin එක Configure කරලා තියෙන නිසා Fat JAR එකක් හදන්න පුළුවන්. මේකෙන් සියලුම Dependencies එකට එකතු වෙලා Single JAR File එකක් හැදෙනවා.
sbt assembly
මේ Command එක Run කලාම target/scala-3.x/
Folder එක ඇතුලේ my-scala-spring-boot-app.jar
වගේ File එකක් හැදෙනවා. ඊට පස්සේ මේක Run කරන්න පුළුවන්.
java -jar target/scala-3.x/my-scala-spring-boot-app.jar
මේක තමයි Production වලට Deploy කරන්න කදිම ක්රමය.
http://localhost:8080/search
(parameter නැතුව):
සෙවීමට කිසිවක් ඇතුලත් කර නොමැත.
http://localhost:8080/search?query=test
(බ්රවුසර් එකේ විවෘත කරන්න):
ඔබ සෙව්වේ: test
http://localhost:8080/greet/Nimal
(බ්රවුසර් එකේ විවෘත කරන්න):
සුභ දවසක්, Nimal! Scala Spring Boot වලින් ඔයාව සාදරයෙන් පිළිගන්නවා.
http://localhost:8080/hello
(බ්රවුසර් එකේ විවෘත කරන්න):
ආයුබෝවන්, Scala සහ Spring Boot ලෝකයට!
Command Line එකෙන් Project Folder එකට ගිහින්:
sbt run
SBT එක Project එක Compile කරලා Spring Boot Application එක Start කරයි. ඔයාලට Console එකේ Output එකේ Started Application in XXX seconds (JVM running for YYY)
වගේ Message එකක් පෙනෙයි.
තව පොඩ්ඩක් ගැඹුරට (A Little Deeper)
අපි දැන් සරල Controller එකක් හදලා Run කලා. ඒත් Spring Boot සහ Scala එකට ගත්තාම කරන්න පුළුවන් දේවල් තවත් ගොඩක් තියෙනවා.
Dependency Injection (DI) සහ Service Layers
අපි උඩ Example එකේ GreetingService
එක Inject කරපු විදිහ දැක්කා. Spring Framework එකේ තියෙන DI Pattern එක Scala වලත් හරියටම වැඩ කරනවා. අපිට පුළුවන් Service Layers, Repository Layers හදලා @Service
, @Repository
වගේ Annotations පාවිච්චි කරලා ඒවා Spring Context එකට Inject කරගන්න.
@Service
class UserService {
def getUserById(id: Long): Option[User] = {
// Logic to fetch user from database or other source
if (id == 1) Some(User(1, "Kamal")) else None
}
}
// Scala Case Class එකක් Data Model එකක් ලෙස
case class User(id: Long, name: String)
Data Access (Spring Data JPA)
Spring Data JPA කියන්නේ Database Operations Manage කරන්න පුළුවන් බලගතු Library එකක්. Scala Case Classes සහ Traits පාවිච්චි කරලා මේකත් Spring Boot Application එකකට Integrate කරන්න පුළුවන්.
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import jakarta.persistence.{Entity, GeneratedValue, GenerationType, Id}
// Entity එකක් ලෙස Scala Case Class එකක්
@Entity
case class Product(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) id: Long,
name: String,
price: Double
)
// Repository Interface එක
@Repository
trait ProductRepository extends JpaRepository[Product, java.lang.Long] {
def findByName(name: String): Option[Product]
}
මෙතනදී වැදගත් වෙන්නේ Scala Case Classes වල Default Constructor එකක් සහ Getters/Setters Automatically Generate වීම. මේ නිසා JPA Mapping එක ලේසි වෙනවා.
Functional Programming Patterns
Scala වල තියෙන Functional Programming හැකියාව Spring Boot Application එකේ Business Logic එක ලියනකොට ගොඩක් ප්රයෝජනවත් වෙනවා. Immutable data structures, Higher-order functions, Pattern matching වගේ දේවල් පාවිච්චි කරලා Bug අඩු, Maintain කරන්න ලේසි Code ලියන්න පුළුවන්.
// Example of functional approach in a service
@Service
class OrderProcessor {
def processOrder(items: List[Item]): Either[String, OrderConfirmation] = {
if (items.isEmpty) Left("No items in order.")
else {
// Complex logic here
val total = items.map(_.price).sum
Right(OrderConfirmation(s"Order processed. Total: $total"))
}
}
}
case class Item(name: String, price: Double)
case class OrderConfirmation(message: String)
Either[Error, Success]
වගේ Scala Types පාවිච්චි කරලා Error Handling එක ගොඩක් Elegantly කරන්න පුළුවන්.
Asynchronous Programming (Futures & Akka)
High-performance Applications වලට Asynchronous Processing ගොඩක් වැදගත්. Spring Boot එකේ WebFlux වගේ Reactive Frameworks තියෙනවා වගේම, Scala වල තියෙන Futures සහ Akka Framework එකත් Spring Boot එක්ක Integrate කරන්න පුළුවන්. මේකෙන් Microservices වල Concurrency සහ Scalability එක තවත් වැඩි කරගන්න පුළුවන්.
Testing
Testing කියන්නේ Software Development වල අත්යවශ්යම දෙයක්. Scala Project වලට ScalaTest, Specs2 වගේ Testing Frameworks තියෙනවා. මේවා Spring Boot Test utilities එක්කම පාවිච්චි කරන්න පුළුවන්.
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.beans.factory.annotation.Autowired
@SpringBootTest
class HelloWorldControllerSpec extends AnyFunSuite with Matchers {
@Autowired
private val controller: HelloWorldController = null
test("sayHello should return greeting message") {
controller.sayHello() shouldEqual "ආයුබෝවන්, Scala සහ Spring Boot ලෝකයට!"
}
test("greetName should return personalized greeting") {
controller.greetName("Amal") shouldEqual "සුභ දවසක්, Amal! Scala Spring Boot වලින් ඔයාව සාදරයෙන් පිළිගන්නවා."
}
}
අවසන් වචන
ඉතින් මචන්ලා, ඔයාලට දැන් හොඳ අවබෝධයක් ඇති Spring Boot සහ Scala එකට පාවිච්චි කරලා මොනවගේ බලගතු Solutions හදන්න පුළුවන්ද කියලා. මේකෙන් අපිට ලැබෙන්නේ Spring Boot වල Production-ready Features සහ Scala වල Expressiveness, Type Safety, Functional Programming හැකියාවන් වල එකතුවක්. මේ Combination එකෙන් වැඩි දියුණු කළ Productivity එකක්, Maintain කරන්න ලේසි, Robust Applications හදන්න පුළුවන්.
ඔයාලා Java වලට ආස නම්, ඒ වගේම Functional Programming වලටත් කැමති නම්, Scala කියන්නේ අනිවාර්යයෙන්ම ඉගෙනගන්න ඕන Language එකක්. ඒ වගේම Spring Boot එක්ක Scala පාවිච්චි කරන එක Backend Development වල අලුත් දොරටුවක් විවෘත කරනවා. මේක පටන් ගන්න ටිකක් අමාරු වෙන්න පුළුවන්, මොකද Concepts ටිකක් වෙනස් නිසා. ඒත්, ටිකක් කාලය දුන්නොත් මේකෙන් ඔයාලට හිතාගන්න බැරි තරම් වාසි ලැබෙයි.
අදම මේ Example එක ඔයාලගේ Machine එකේ Run කරලා බලන්න. තව මොනවගේ දේවල් Spring Boot එක්ක Scala වලින් කරන්න පුළුවන්ද කියලා Explore කරන්න. ඔයාලට තියෙන ප්රශ්න, අදහස්, ඒ වගේම මේ ගැන තවත් දැනගන්න ඕන දේවල් තියෙනවා නම් පහළින් කමෙන්ට් එකක් දාන්න. අපි ඊළඟ Blog Post එකෙන් හම්බවෙමු! සුභ දවසක්!