স্কালা একটি খুবই শক্তিশালী এবং বহুমুখী ভাষা যা বিভিন্ন ওয়েব সার্ভিস এবং RESTful API তৈরিতে ব্যবহৃত হয়। স্কালায় HTTP রিকোয়েস্ট এবং রেসপন্স হ্যান্ডল করার জন্য Akka HTTP, Play Framework, অথবা Http4s এর মতো ফ্রেমওয়ার্ক ব্যবহৃত হয়। এই টিউটোরিয়ালে, আমরা Akka HTTP ব্যবহার করে কিভাবে একটি REST API তৈরি করা যায় তা আলোচনা করব।
১. Akka HTTP দিয়ে REST API তৈরি করা
Akka HTTP হল একটি শক্তিশালী এবং জনপ্রিয় ওয়েব ফ্রেমওয়ার্ক যা স্কালায় HTTP সার্ভার এবং ক্লায়েন্ট তৈরি করতে ব্যবহৃত হয়। এটি Akka ইঞ্জিনের উপর ভিত্তি করে তৈরি, যা মাল্টিথ্রেডিং এবং কনকারেন্সি ম্যানেজমেন্টের জন্য খুবই শক্তিশালী। Akka HTTP আপনাকে সহজেই REST API তৈরি করতে সাহায্য করে।
১.১ প্রাথমিক প্রজেক্ট কনফিগারেশন
Akka HTTP ব্যবহার করার জন্য আপনার প্রোজেক্টে নিম্নলিখিত ডিপেন্ডেন্সি যুক্ত করতে হবে। যদি আপনি SBT ব্যবহার করেন, তাহলে build.sbt ফাইলে এই ডিপেন্ডেন্সিগুলি যুক্ত করুন:
name := "ScalaHttpExample"
version := "1.0"
scalaVersion := "2.13.6"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % "10.2.7",
"com.typesafe.akka" %% "akka-stream" % "2.6.18",
"com.typesafe.akka" %% "akka-actor" % "2.6.18",
"com.typesafe.akka" %% "akka-http-spray-json" % "10.2.7"
)akka-http: HTTP সার্ভার এবং ক্লায়েন্টের জন্য।akka-stream: অ্যাসিঙ্ক্রোনাস স্ট্রিম হ্যান্ডলিংয়ের জন্য।akka-actor: অ্যাক্টর মডেল ব্যবহারের জন্য।akka-http-spray-json: JSON পার্সিংয়ের জন্য।
১.২ Akka HTTP সার্ভার তৈরি করা
এখন, স্কালায় একটি সাধারন HTTP সার্ভার তৈরি করার উদাহরণ দেখা যাক যা REST API হ্যান্ডল করতে সক্ষম।
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.model.StatusCodes
import scala.concurrent.ExecutionContext
object HttpServerExample {
def main(args: Array[String]): Unit = {
implicit val system: ActorSystem = ActorSystem("http-system")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContext = system.dispatcher
val route =
path("hello") {
get {
complete("Hello, World!") // Handle GET request at /hello endpoint
}
} ~
path("greet" / Segment) { name =>
get {
complete(s"Hello, $name!") // Handle GET request with dynamic path parameter
}
}
Http().newServerAt("localhost", 8080).bind(route)
println("Server started at http://localhost:8080/")
}
}এখানে:
- ActorSystem এবং ActorMaterializer হলো Akka HTTP স্ট্রিমিং এবং অ্যাক্টর ব্যবস্থাপনা।
pathএবংgetডিরেক্টিভস ব্যবহার করে রাউটিং করা হচ্ছে। এখানেhelloএবংgreet(যে কোনও নাম গ্রহণ করবে) দুইটি এন্ডপয়েন্ট তৈরি করা হয়েছে।completeমেথডে আপনি সার্ভারের রেসপন্স কনফিগার করেন।
১.৩ ক্লায়েন্ট সাইড HTTP রিকোয়েস্ট
এখন দেখব কিভাবে Akka HTTP ব্যবহার করে স্কালায় HTTP রিকোয়েস্ট পাঠানো যায়। আমরা Http() ক্লাস ব্যবহার করব।
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import scala.concurrent.{ExecutionContext, Future}
object HttpClientExample {
implicit val system: ActorSystem = ActorSystem("client-system")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContext = system.dispatcher
def main(args: Array[String]): Unit = {
val responseFuture: Future[HttpResponse] =
Http().singleRequest(HttpRequest(uri = "http://localhost:8080/hello"))
responseFuture.onComplete {
case scala.util.Success(response) =>
println(s"Response: ${response.status}")
Unmarshal(response.entity).to[String].foreach(println)
case scala.util.Failure(exception) =>
println(s"Request failed: $exception")
}
}
}এখানে:
singleRequestমেথডের মাধ্যমে একটি GET রিকোয়েস্ট পাঠানো হয়েছে এবং রেসপন্সে যেকোনো স্ট্যাটাস এবং কনটেন্ট পাওয়ার পর তা প্রিন্ট করা হচ্ছে।
২. REST API হ্যান্ডলিং
REST API গুলি HTTP প্রোটোকল এবং JSON ডেটা ট্রান্সফার ফরম্যাট ব্যবহার করে ক্লায়েন্ট এবং সার্ভারের মধ্যে যোগাযোগ স্থাপন করে। স্কালায় Akka HTTP ব্যবহার করে REST API তৈরি করা বেশ সোজা। এখানে আমরা আরও কিছু REST API endpoint উদাহরণ দেখব:
২.১ POST এবং JSON প্যার্সিং
স্কালায় Akka HTTP JSON প্যার্সিংয়ের জন্য spray-json বা circe ব্যবহার করা যায়। এখানে spray-json ব্যবহার করা হবে।
উদাহরণ:
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.DefaultJsonProtocol
case class Person(name: String, age: Int)
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val personFormat = jsonFormat2(Person)
}
object RestApiExample extends JsonSupport {
def main(args: Array[String]): Unit = {
val route =
path("person") {
post {
entity(as[Person]) { person =>
complete(StatusCodes.OK, s"Received person: ${person.name}, Age: ${person.age}")
}
}
}
Http().newServerAt("localhost", 8080).bind(route)
println("Server started at http://localhost:8080/")
}
}এখানে:
jsonFormat2ব্যবহার করেPersonক্লাসের জন্য JSON ফর্ম্যাট তৈরি করা হয়েছে।entity(as[Person])ব্লকে ক্লায়েন্ট থেকে JSON ডেটা গ্রহণ করা হচ্ছে এবং তাPersonঅবজেক্টে রূপান্তরিত করা হচ্ছে।
৩. Play Framework দিয়ে REST API তৈরি করা
Play Framework স্কালায় আরও একটি জনপ্রিয় ওয়েব ফ্রেমওয়ার্ক, যা RESTful API তৈরি করতে সহায়তা করে। Play HTTP সার্ভার এবং রাউটিং ব্যবস্থাপনা, JSON পার্সিং এবং অ্যাসিঙ্ক্রোনাস অপারেশন খুবই সহজে পরিচালনা করতে সক্ষম।
৩.১ Play Framework সেটআপ
Play ফ্রেমওয়ার্কের মাধ্যমে REST API তৈরি করতে আপনাকে build.sbt ফাইলে Play ডিপেন্ডেন্সি যুক্ত করতে হবে।
name := "PlayRestApiExample"
version := "1.0"
scalaVersion := "2.13.6"
libraryDependencies ++= Seq(
guice,
"com.typesafe.play" %% "play" % "2.8.8"
)৩.২ Controller এবং JSON
import play.api.mvc._
import play.api.libs.json._
case class Person(name: String, age: Int)
object Person {
implicit val personFormat = Json.format[Person]
}
class ApiController(cc: ControllerComponents) extends AbstractController(cc) {
def getPerson = Action {
val person = Person("Alice", 25)
Ok(Json.toJson(person))
}
def postPerson = Action(parse.json) { request =>
request.body.validate[Person].map { person =>
Ok(s"Received person: ${person.name}, Age: ${person.age}")
}.getOrElse(BadRequest("Invalid JSON"))
}
}এখানে:
Json.format[Person]JSON ফর্ম্যাট তৈরি করছেPersonক্লাসের জন্য।Action(parse.json)ব্যবহারের মাধ্যমে JSON ডেটা গ্রহণ এবং প্রসেস করা হচ্ছে।
সারাংশ
স্কালায় Akka HTTP এবং Play Framework ব্যবহার করে RESTful API তৈরি করা খুবই সহজ এবং শক্তিশালী। Akka HTTP দিয়ে খুবই সহজে ওয়েব সার্ভার এবং
ক্লায়েন্ট তৈরি করা যায়, যেখানে HTTP রিকোয়েস্ট এবং রেসপন্স হ্যান্ডল করা হয়। Play Framework একটি ফিচার-রিচড ওয়েব ফ্রেমওয়ার্ক যা REST API তৈরি করতে ব্যবহৃত হয় এবং JSON পার্সিং, রাউটিং, এবং অ্যাসিঙ্ক্রোনাস প্রক্রিয়া সমর্থন করে। স্কালায় এই ফ্রেমওয়ার্কগুলো ব্যবহার করে দ্রুত এবং কার্যকরী ওয়েব অ্যাপ্লিকেশন তৈরি করা সম্ভব।
Play Framework একটি শক্তিশালী, হালকা, এবং ফাংশনাল ওয়েব ফ্রেমওয়ার্ক যা মূলত Scala এবং Java দিয়ে ওয়েব অ্যাপ্লিকেশন তৈরি করার জন্য ব্যবহৃত হয়। এটি অ্যাসিনক্রোনাস, রিএ্যাক্টিভ প্রোগ্রামিং (reactive programming)-এ তৈরি একটি ফ্রেমওয়ার্ক যা HTTP সার্ভার, ফিচার রিচ রাউটিং, এবং সেশন ম্যানেজমেন্ট সুবিধা প্রদান করে।
Play Framework "developer-friendly" এবং "scalable" হওয়ায়, এটি ওয়েব অ্যাপ্লিকেশন ডেভেলপমেন্টে জনপ্রিয় হয়ে উঠেছে।
১. Play Framework এর বৈশিষ্ট্য
- অ্যাসিনক্রোনাস প্রোগ্রামিং: Play Framework সম্পূর্ণ অ্যাসিনক্রোনাস ও ব্লকিং-লেস (non-blocking) আর্কিটেকচার ব্যবহার করে, যা উচ্চ পারফরম্যান্স নিশ্চিত করে।
- স্কালা এবং জাভা সমর্থন: এটি স্কালা এবং জাভা উভয় ভাষার জন্য সমর্থিত, তবে স্কালার জন্য এটি আরো শক্তিশালী এবং উপযোগী।
- রিএ্যাক্টিভ ফ্রেমওয়ার্ক: Play Framework রিএ্যাক্টিভ স্টাইলের উন্নত অ্যাপ্লিকেশন ডেভেলপমেন্ট সমর্থন করে, যা ব্যবহারকারীর প্রয়োজন অনুযায়ী স্কেল করতে পারে।
- সিরিয়ালাইজেশন ও JSON সমর্থন: এটি স্বয়ংক্রিয়ভাবে JSON ডেটা পার্স এবং সিরিয়ালাইজ করতে সক্ষম।
- কমপাইল টাইম ফিচার: Play Framework কোডের "live reloading" সুবিধা প্রদান করে, যার মাধ্যমে আপনি কোড পরিবর্তন করলে সার্ভার পুনরায় চালু না করে অটোমেটিকভাবে পরিবর্তন দেখতে পাবেন।
২. Play Framework এর জন্য স্কালা সেটআপ
Play Framework-এর স্কালা ভার্সন ব্যবহার করার জন্য প্রথমে আপনাকে sbt (Simple Build Tool) সেটআপ করতে হবে। এটি স্কালার জন্য একটি বিল্ড টুল যা ডিপেন্ডেন্সি ম্যানেজমেন্ট এবং বিল্ড প্রক্রিয়া সহজ করে তোলে।
২.১ প্রথম Play Framework অ্যাপ্লিকেশন তৈরি করা
এখানে একটি সাধারণ Play Framework অ্যাপ্লিকেশন সেটআপ এবং রান করার প্রক্রিয়া দেওয়া হল:
প্রোজেক্ট তৈরি করুন:
Play Framework অ্যাপ্লিকেশন তৈরি করার জন্য প্রথমে sbt ডাউনলোড এবং ইনস্টল করতে হবে। আপনি নিচের কমান্ডের মাধ্যমে Play প্রোজেক্ট তৈরি করতে পারেন:
sbt new playframework/play-scala-seed.g8এটি একটি নতুন Play Framework প্রোজেক্ট তৈরি করবে।
প্রোজেক্ট ফোল্ডার তৈরি হওয়া পরে:
cd your-project-namePlay অ্যাপ্লিকেশন রান করুন:
Play Framework অ্যাপ্লিকেশন রান করতে, আপনাকে শুধুমাত্র নিচের কমান্ডটি চালাতে হবে:
sbt runএর পর আপনি ব্রাউজারে গিয়ে অ্যাপ্লিকেশন দেখতে পারবেন:
http://localhost:9000- অ্যাপ্লিকেশন কোড দেখুন:
app/controllers/HomeController.scalaফাইলে আপনার কোড লেখা শুরু হবে।app/views/index.scala.htmlফাইলে HTML টেমপ্লেট রেন্ডার করা হবে।
উদাহরণ: সাধারণ অ্যাপ্লিকেশন কোড
HomeController.scala:
package controllers
import play.api.mvc._
class HomeController(cc: ControllerComponents) extends AbstractController(cc) {
def index() = Action {
Ok("Hello, Play Framework with Scala!")
}
}এখানে:
HomeControllerএকটি সাধারণ কন্ট্রোলার ক্লাস যা একটি একক অ্যাকশনindex()তৈরি করেছে।Actionহল Play Framework এর একটি ফিচার, যা HTTP রিকোয়েস্টের জন্য বিভিন্ন ধরনের রেসপন্স প্রস্তুত করে।
routes ফাইল:
GET / controllers.HomeController.index()এখানে:
routesফাইলটি Play Framework এর URL রাউটিং পরিচালনা করে, যেখানে রিকোয়েস্ট এবং কন্ট্রোলারের অ্যাকশনটি সংযুক্ত থাকে।
৩. Play Framework এর অ্যাডভান্সড ফিচার
কনফিগারেশন: Play Framework JSON এবং ডাটাবেস কনফিগারেশন, অ্যাপ্লিকেশন কনফিগারেশন এবং প্রপার্টি ফাইলের মাধ্যমে সিস্টেম সেটআপ পরিচালনা করতে সহায়তা করে।
application.conf:
play.http.secret.key="your-secret-key"JSON পার্সিং: Play Framework JSON ডাটা প্রক্রিয়াকরণে সহায়তা করে, যা API ডেভেলপমেন্টের জন্য খুবই উপকারী।
উদাহরণ:
import play.api.libs.json._ val json = Json.parse("""{"name": "Alice", "age": 25}""") val name = (json \ "name").as[String] val age = (json \ "age").as[Int] println(s"Name: $name, Age: $age")Database Integration: Play Framework স্কালার জন্য Slick অথবা Anorm ব্যবহার করে ডাটাবেস সংযোগ এবং কোয়েরি পরিচালনা করতে সক্ষম।
উদাহরণ:
Slickব্যবহার করে ডাটাবেস ইন্টিগ্রেশন:val db = Database.forConfig("mydb") val users = db.run(sql"SELECT * FROM users".as[User])- WebSocket: Play Framework ওয়েবসকেটস (real-time communication) সমর্থন করে, যা চ্যাট অ্যাপ্লিকেশন বা রিয়েল-টাইম ডাটা এক্সচেঞ্জের জন্য ব্যবহৃত হয়।
৪. Play Framework এর জন্য রাউটিং এবং টেমপ্লেট
রাউটিং (Routing) Play Framework এ URL রাউটিং খুবই গুরুত্বপূর্ণ, যেখানে URL পাথ এবং কন্ট্রোলার অ্যাকশনগুলোর মধ্যে সম্পর্ক তৈরি হয়।
routes ফাইলের মাধ্যমে আমরা URL এবং অ্যাকশন সেট আপ করি:
GET /home controllers.HomeController.index()
GET /about controllers.HomeController.about()টেমপ্লেট (Template) Play Framework Scala তে HTML টেমপ্লেট রেন্ডার করার জন্য Twirl টেমপ্লেট ইঞ্জিন ব্যবহার করে, যা সহজেই HTML, JavaScript, CSS ইত্যাদি ফাইল তৈরি করতে সহায়তা করে।
index.scala.html:
@(message: String)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Play Framework</title>
</head>
<body>
<h1>@message</h1>
</body>
</html>এখানে:
@messageহল একটি ভ্যারিয়েবল যা কন্ট্রোলার থেকে পাস করা হয় এবং HTML এ রেন্ডার করা হয়।
৫. Play Framework এবং Scalacode
Play Framework স্কালার সাথে একত্রিত হয়ে আপনাকে খুব দ্রুত এবং সহজে স্কেলেবল ওয়েব অ্যাপ্লিকেশন তৈরি করতে সহায়তা করে। এটি প্রোডাকশনে যাওয়ার আগে ডেভেলপমেন্টের জন্য অত্যন্ত উপকারী কারণ এর স্বয়ংক্রিয় live reload সুবিধা রয়েছে, যা কোডে পরিবর্তন করার সাথে সাথে সরাসরি ফলাফল দেখতে দেয়।
সারাংশ
- Play Framework স্কালার জন্য একটি শক্তিশালী ওয়েব ফ্রেমওয়ার্ক যা অ্যাসিনক্রোনাস, রিএ্যাক্টিভ প্রোগ্রামিং সমর্থন করে।
- SBT ব্যবহার করে Play অ্যাপ্লিকেশন তৈরি এবং রান করা হয়।
- ফিউচার এবং প্রমিস ব্যবহার করে Play অ্যাপ্লিকেশনে অ্যাসিনক্রোনাস অপারেশন পরিচালনা করা যায়।
- Routes এবং Twirl Templates ব্যবহার করে URL রাউটিং এবং HTML রেন্ডারিং খুব সহজ হয়।
Play Framework স্কালার জন্য একটি দুর্দান্ত টুল যা ওয়েব অ্যাপ্লিকেশন ডেভেলপমেন্টকে সহজ, দ্রুত, এবং স্কেলযোগ্য করে তোলে।
স্কালায় REST API তৈরি করতে সাধারণত Akka HTTP, Play Framework, অথবা http4s ফ্রেমওয়ার্ক ব্যবহৃত হয়। এই ফ্রেমওয়ার্কগুলি স্কালায় HTTP সার্ভিস তৈরি এবং পরিচালনা করার জন্য অত্যন্ত কার্যকরী। তবে, এখানে আমরা Akka HTTP ব্যবহার করে একটি সিম্পল REST API তৈরি করার উদাহরণ দেখব, যা খুবই জনপ্রিয় এবং শক্তিশালী একটি ফ্রেমওয়ার্ক।
১. Akka HTTP দিয়ে REST API তৈরি
১.১ প্রথমে ডিপেন্ডেন্সি যোগ করা
Akka HTTP এর জন্য স্কালার sbt বিল্ড টুল ব্যবহার করা হয়। প্রথমে আপনার build.sbt ফাইলটি সঠিক ডিপেন্ডেন্সি দিয়ে কনফিগার করতে হবে।
name := "AkkaHttpRestApi"
version := "0.1"
scalaVersion := "2.13.6"
// Akka HTTP Dependencies
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % "10.2.7",
"com.typesafe.akka" %% "akka-stream" % "2.6.16",
"com.typesafe.akka" %% "akka-actor-typed" % "2.6.16",
"com.typesafe.akka" %% "akka-http-spray-json" % "10.2.7"
)এখানে, আমরা akka-http এবং akka-stream লাইব্রেরিগুলি ব্যবহার করছি, যা Akka HTTP এর জন্য অপরিহার্য। এছাড়া JSON সাপোর্ট এর জন্য akka-http-spray-json লাইব্রেরি যোগ করা হয়েছে।
১.২ Akka HTTP সেটআপ
এখন আমরা একটি সিম্পল Akka HTTP সার্ভার তৈরি করব, যা একটি REST API এর মাধ্যমে HTTP GET এবং POST রিকোয়েস্ট পরিচালনা করবে।
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.model.StatusCodes
import spray.json.DefaultJsonProtocol._
import spray.json._
import scala.concurrent.ExecutionContextExecutor
import scala.io.StdIn
// Case class for JSON
case class User(name: String, age: Int)
// JSON format for User
object UserJsonProtocol extends DefaultJsonProtocol {
implicit val userFormat = jsonFormat2(User)
}
object Main extends App {
// Akka HTTP setup
implicit val system: ActorSystem = ActorSystem("rest-api-system")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContextExecutor = system.dispatcher
// Route setup
import UserJsonProtocol._
val route =
pathPrefix("api") {
// GET endpoint to return a user as JSON
path("user" / Segment) { name =>
get {
complete {
val user = User(name, 25)
user.toJson.prettyPrint // Convert user to pretty-printed JSON
}
}
} ~
// POST endpoint to accept a user in JSON format
path("user") {
post {
entity(as[String]) { userData =>
val user = userData.parseJson.convertTo[User]
complete {
s"Received user: ${user.name}, age: ${user.age}"
}
}
}
}
}
// Start the server
val bindingFuture = Http().newServerAt("localhost", 8080).bind(route)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // Wait for user input to shut down
bindingFuture
.flatMap(_.unbind()) // Unbind the server
.onComplete(_ => system.terminate()) // Shutdown system
}১.৩ এটি কি করছে?
ActorSystemএবংActorMaterializer: Akka HTTP সার্ভার চালাতে এই দুটি অবজেক্ট প্রয়োজন।ActorSystemহলো অ্যাক্টর মডেল চালানোর জন্য ব্যবহৃত মূল সিস্টেম, এবংActorMaterializerহল স্ট্রিম ম্যানেজমেন্টের জন্য ব্যবহৃত।pathPrefixএবংpath: HTTP রুট ডিফাইন করা হচ্ছে। একাধিক রুট একসাথে মিলিয়ে API তৈরির জন্যpathPrefixএবংpathব্যবহৃত হচ্ছে।- GET endpoint:
GET /api/user/{name}রিকোয়েস্টটি একটিUserঅবজেক্ট ফেরত দেয়। এখানেUserএকটি কেস ক্লাস, যা স্ক্যালার JSON ফরম্যাটে রূপান্তরিত হয়েছে। - POST endpoint:
POST /api/userরিকোয়েস্টটি JSON ডেটা গ্রহণ করে এবং একটি নতুনUserতৈরি করে প্রাপ্ত তথ্যটি ফেরত দেয়। - JSON ফরম্যাটিং: Akka HTTP JSON প্রক্রিয়াকরণের জন্য
spray-jsonলাইব্রেরি ব্যবহার করা হয়েছে।
২. আবশ্যক লাইব্রেরি ইনস্টলেশন
যেহেতু আমরা JSON ডেটা প্রসেস করতে spray-json লাইব্রেরি ব্যবহার করেছি, এটি আমাদের build.sbt ফাইলে যুক্ত করা আছে।
"com.typesafe.akka" %% "akka-http-spray-json" % "10.2.7"এই লাইব্রেরিটি Akka HTTP এর সাথে JSON প্রক্রিয়াকরণকে সহজ করে দেয়, যেমন JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন।
৩. রানিং এবং টেস্টিং
Akka HTTP সার্ভার চালানো:
আপনার স্কালা প্রোজেক্ট রান করার জন্য, নিম্নলিখিত কমান্ড ব্যবহার করুন:sbt runএটি আপনার অ্যাপ্লিকেশন শুরু করবে এবং
localhost:8080এ REST API চালু করবে।GET রিকোয়েস্ট টেস্ট করা:
একটি ব্রাউজারে বাcurlদিয়ে GET রিকোয়েস্ট পাঠাতে পারেন:curl http://localhost:8080/api/user/Johnআউটপুট:
{"name":"John","age":25}POST রিকোয়েস্ট টেস্ট করা:
একটিcurlদিয়ে POST রিকোয়েস্ট পাঠাতে পারেন:curl -X POST http://localhost:8080/api/user -d '{"name": "Alice", "age": 30}' -H "Content-Type: application/json"আউটপুট:
Received user: Alice, age: 30
৪. একে বড় আকারে স্কেল করা
Akka HTTP এর সাহায্যে আপনি সহজেই একটি REST API বড় আকারে স্কেল করতে পারবেন। আপনি Akka Cluster, Akka Streams, এবং Akka HTTP এর বিভিন্ন ফিচার ব্যবহার করে ডিসট্রিবিউটেড সিস্টেম এবং হাই লোডের জন্য উপযোগী API তৈরি করতে পারবেন।
সারাংশ
- Akka HTTP স্কালায় একটি শক্তিশালী HTTP সার্ভিস তৈরি করার জন্য ব্যবহৃত ফ্রেমওয়ার্ক।
- এটি Actor Model ভিত্তিক এবং পারফরম্যান্স এবং স্কেলেবিলিটি অত্যন্ত ভালো।
- স্কালায় REST API তৈরি করার জন্য Akka HTTP সহজেই GET, POST, PUT, DELETE রিকোয়েস্ট পরিচালনা করতে সক্ষম।
- spray-json লাইব্রেরির মাধ্যমে JSON প্রক্রিয়াকরণ করা যায়।
এই উদাহরণটি একটি সিম্পল REST API তৈরি করার একটি প্রাথমিক গাইড। Akka HTTP এর আরও উন্নত বৈশিষ্ট্য যেমন ফিচার ফ্ল্যাগ, সেশন ম্যানেজমেন্ট, মডিউলার ডিপেন্ডেন্সি ইত্যাদি প্রয়োগের মাধ্যমে বড় এবং স্কেলেবল API তৈরি করা সম্ভব।
JSON (JavaScript Object Notation) হল একটি হালকা, পাঠযোগ্য ডেটা বিনিময় ফরম্যাট যা সিস্টেম বা অ্যাপ্লিকেশনগুলির মধ্যে ডেটা আদান-প্রদানে ব্যাপকভাবে ব্যবহৃত হয়। স্কালায় JSON প্রসেসিং এবং সিরিয়ালাইজেশন করার জন্য বিভিন্ন লাইব্রেরি এবং টুলস রয়েছে। সাধারণত Play JSON, circe, এবং json4s লাইব্রেরি স্কালার মধ্যে JSON প্রসেসিং এবং সিরিয়ালাইজেশন করতে ব্যবহৃত হয়।
এখানে আমরা Play JSON এবং circe লাইব্রেরির সাহায্যে স্কালায় JSON প্রসেসিং এবং সিরিয়ালাইজেশন দেখব।
১. Play JSON
Play JSON হল একটি জনপ্রিয় JSON লাইব্রেরি যা Play Framework দ্বারা সরবরাহিত। এটি JSON ডেটাকে সহজে পার্স (parse) এবং সিরিয়ালাইজ (serialize) করার জন্য ব্যবহৃত হয়।
১.১ Play JSON লাইব্রেরি সেটআপ
প্রথমে আপনার build.sbt ফাইলে Play JSON লাইব্রেরি অন্তর্ভুক্ত করতে হবে:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.2"১.২ JSON সিরিয়ালাইজেশন ও ডেসিরিয়ালাইজেশন
Play JSON লাইব্রেরি দিয়ে JSON সিরিয়ালাইজেশন (অবজেক্ট থেকে JSON স্ট্রিং) এবং ডেসিরিয়ালাইজেশন (JSON স্ট্রিং থেকে অবজেক্ট) করা যায়।
JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন উদাহরণ:
import play.api.libs.json._
case class Person(name: String, age: Int)
// Implicit format for JSON conversion
object Person {
implicit val personFormat: OFormat[Person] = Json.format[Person]
}
object PlayJsonExample {
def main(args: Array[String]): Unit = {
// Creating an instance of Person
val person = Person("Alice", 30)
// Serializing Person to JSON
val json = Json.toJson(person)
println(json) // Output: {"name":"Alice","age":30}
// Deserializing JSON to Person
val jsonString = """{"name":"Bob","age":25}"""
val jsonObject = Json.parse(jsonString)
val parsedPerson = jsonObject.as[Person]
println(parsedPerson) // Output: Person(Bob,25)
}
}এখানে:
Json.toJson()মেথড ব্যবহার করে অবজেক্টকে JSON এ রূপান্তরিত করা হচ্ছে।Json.parse()এবংas[]ব্যবহার করে JSON ডেটাকে Scala অবজেক্টে রূপান্তরিত করা হচ্ছে।
২. Circe
Circe একটি হালকা এবং দ্রুত JSON লাইব্রেরি যা স্কালার মধ্যে JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন করার জন্য ব্যবহৃত হয়। Circe স্কালার জন্য ফাংশনাল প্রোগ্রামিং প্যাটার্ন অনুসরণ করে।
২.১ Circe লাইব্রেরি সেটআপ
Circe লাইব্রেরি ব্যবহার করতে হলে আপনাকে আপনার build.sbt ফাইলে নিচের লাইব্রেরি ডিপেন্ডেন্সি যুক্ত করতে হবে:
libraryDependencies += "io.circe" %% "circe-core" % "0.14.1",
"io.circe" %% "circe-generic" % "0.14.1",
"io.circe" %% "circe-parser" % "0.14.1"২.২ JSON সিরিয়ালাইজেশন ও ডেসিরিয়ালাইজেশন
Circe লাইব্রেরির মাধ্যমে JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন করা যায়। Circe সাধারণত io.circe.generic.auto._ এবং io.circe.syntax._ ব্যবহার করে।
Circe উদাহরণ:
import io.circe._
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._
case class Person(name: String, age: Int)
object CirceExample {
def main(args: Array[String]): Unit = {
// Creating an instance of Person
val person = Person("Alice", 30)
// Serializing Person to JSON
val json: Json = person.asJson
println(json) // Output: {"name":"Alice","age":30}
// Deserializing JSON to Person
val jsonString = """{"name":"Bob","age":25}"""
val decodedPerson = decode[Person](jsonString)
decodedPerson match {
case Right(person) => println(person) // Output: Person(Bob,25)
case Left(error) => println(s"Error: $error")
}
}
}এখানে:
asJsonব্যবহার করেPersonঅবজেক্টকে JSON-এ রূপান্তর করা হয়েছে।decode[Person]ব্যবহার করে JSON স্ট্রিংকেPersonঅবজেক্টে ডেসিরিয়ালাইজ করা হয়েছে।
৩. JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন তুলনা (Play JSON vs Circe)
- Play JSON:
- ব্যবহার করা সহজ এবং Play Framework-এ প্রাক-কনফিগারড।
- JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশনের জন্য সোজা এবং সহজ কাস্টম ফরম্যাট তৈরি করতে সক্ষম।
- ভালোভাবে ইন্টিগ্রেটেড Play Framework-এর সাথে।
- Circe:
- ফাংশনাল স্টাইল এবং উচ্চমানের পারফরম্যান্স প্রদান করে।
- সরল এবং শক্তিশালী JSON ডেটা প্রসেসিংয়ের জন্য প্যাকেজ এবং কাস্টম ডেসিরিয়ালাইজেশন/সিরিয়ালাইজেশন সমর্থন করে।
io.circe.generic.auto._ব্যবহার করে সহজেই generic derivation করতে পারে।
৪. JSON Validation
স্কালায় JSON ভ্যালিডেশন করার জন্য আপনি Play JSON বা Circe-এর মাধ্যমে বিভিন্ন কাস্টম ভ্যালিডেশন করতে পারেন। উদাহরণস্বরূপ, কোন ভ্যালু যদি নির্দিষ্ট রেঞ্জের মধ্যে না থাকে, বা কোন ফিল্ড যদি অনুপস্থিত থাকে তবে তা চেক করা যায়।
উদাহরণ: Play JSON Validation
import play.api.libs.json._
case class Person(name: String, age: Int)
object Person {
implicit val personFormat: OFormat[Person] = Json.format[Person]
}
object PlayJsonValidationExample {
def main(args: Array[String]): Unit = {
val invalidJson = Json.obj("name" -> "Alice")
val result = invalidJson.validate[Person]
result match {
case JsSuccess(person, _) => println(s"Valid person: $person")
case JsError(errors) => println(s"Errors: $errors")
}
}
}এখানে:
validateমেথড ব্যবহার করে JSON এর মধ্যে থাকাPersonঅবজেক্টের সঠিকতা যাচাই করা হচ্ছে।JsErrorএর মাধ্যমে যদি কোন ত্রুটি থাকে, তা আউটপুট করা হয়।
সারাংশ
- JSON প্রসেসিং এবং সিরিয়ালাইজেশন স্কালায় সহজভাবে করা যায় বিভিন্ন লাইব্রেরির মাধ্যমে, যেমন Play JSON এবং Circe।
- Play JSON সহজ এবং দ্রুত JSON প্রসেসিং প্রদান করে, বিশেষত যখন Play Framework ব্যবহার করা হয়।
- Circe ফাংশনাল প্রোগ্রামিং স্টাইলে আরও শক্তিশালী JSON প্রসেসিং সমাধান প্রদান করে, এবং
Generic Derivation-এর মাধ্যমে কম কোডে টাইপ সেফ JSON সিরিয়ালাইজেশন/ডেসিরিয়ালাইজেশন করতে সাহায্য করে।
এই লাইব্রেরিগুলি ব্যবহার করে আপনি JSON ডেটার সাথে সহজেই কাজ করতে পারবেন এবং কোডের কার্যকারিতা ও পাঠযোগ্যতা উন্নত করতে পারবেন।
Akka HTTP এবং Akka Streams স্কালার জন্য দুটি অত্যন্ত শক্তিশালী লাইব্রেরি, যা রিয়েল-টাইম ওয়েব সার্ভিস এবং ডেটা স্ট্রিমিং প্রক্রিয়াগুলির জন্য ব্যবহৃত হয়। Akka HTTP একটি HTTP সার্ভার তৈরি করতে এবং ক্লায়েন্টের জন্য HTTP রিকোয়েস্ট পাঠাতে ব্যবহৃত হয়, আর Akka Streams একটি reactive স্ট্রিম প্রসেসিং লাইব্রেরি যা ডেটা স্ট্রিমের উপর প্রক্রিয়া সম্পাদন করে।
এখানে Akka HTTP এবং Akka Streams সম্পর্কে বিস্তারিত আলোচনা করা হবে এবং কীভাবে এগুলি স্কালায় ওয়েব সার্ভিস এবং ডেটা স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করতে ব্যবহার করা যায় তা উদাহরণসহ ব্যাখ্যা করা হবে।
১. Akka HTTP
Akka HTTP হল একটি lightweight HTTP ফ্রেমওয়ার্ক যা HTTP সার্ভার এবং ক্লায়েন্ট তৈরি করার জন্য ব্যবহৃত হয়। এটি Akka প্ল্যাটফর্মের উপর ভিত্তি করে তৈরি এবং reactive programming ধারণা অনুসরণ করে।
Akka HTTP-তে সাধারণ ওয়েব সার্ভিস তৈরি করা
Akka HTTP ডিপেন্ডেন্সি যোগ করা:
আপনার
build.sbtফাইলে নিচের ডিপেন্ডেন্সি যোগ করুন:libraryDependencies += "com.typesafe.akka" %% "akka-http" % "10.2.6" libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.6.14"একটি সাধারণ HTTP সার্ভার তৈরি করা:
এখানে একটি সাধারণ Akka HTTP সার্ভারের উদাহরণ দেয়া হলো, যা HTTP রিকোয়েস্ট গ্রহণ করে এবং HTTP রেসপন্স পাঠায়।
import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer import akka.http.scaladsl.model.StatusCodes object AkkaHttpServer { def main(args: Array[String]): Unit = { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val executionContext = system.dispatcher // Define the route (endpoint) val route = path("hello") { get { complete(StatusCodes.OK, "Hello, Akka HTTP!") } } // Bind the HTTP server to a port Http().newServerAt("localhost", 8080).bind(route) println("Server started at http://localhost:8080/") } }এখানে:
path("hello"): একটি HTTP রাউট তৈরি করা হয়েছে, যা/helloপাথে GET রিকোয়েস্ট গ্রহণ করবে।complete: এটি রেসপন্স তৈরি করে, যেখানে "Hello, Akka HTTP!" বার্তা পাঠানো হবে।Http().newServerAt("localhost", 8080): এই লাইনটি সার্ভারকে লোকালহোস্টের 8080 পোর্টে চালু করে।
ক্লায়েন্ট HTTP রিকোয়েস্ট করা:
Akka HTTP ক্লায়েন্টের সাহায্যে আপনি HTTP রিকোয়েস্ট পাঠাতে পারেন। নিচে এর উদাহরণ:
import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.ActorMaterializer object AkkaHttpClient { def main(args: Array[String]): Unit = { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val executionContext = system.dispatcher val responseFuture = Http().singleRequest(HttpRequest(uri = "http://localhost:8080/hello")) responseFuture.flatMap { response => Unmarshal(response.entity).to[String].map { body => println(s"Response: $body") } } } }এখানে:
singleRequest: HTTP রিকোয়েস্ট পাঠানোর জন্য ব্যবহৃত হয়।Unmarshal(response.entity).to[String]: রেসপন্সের বডি থেকে স্ট্রিং আউটপুট বের করা হয়।
২. Akka Streams
Akka Streams হল একটি reactive streams লাইব্রেরি যা স্কালায় ডেটা প্রসেসিংয়ের জন্য ব্যবহৃত হয়। এটি একটি backpressure মেকানিজম ব্যবহার করে, যা ডেটা স্ট্রিমের গতিকে নিয়ন্ত্রণ করে। Akka Streams, Akka Actor Model এবং Akka HTTP-এর সাথে একত্রে কাজ করে।
Akka Streams এর মাধ্যমে ডেটা প্রসেসিং
Akka Streams ডিপেন্ডেন্সি যোগ করা:
আপনার
build.sbtফাইলে নিচের ডিপেন্ডেন্সি যোগ করুন:libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.6.14"Akka Streams ফ্লো (Flow) তৈরি করা:
এখানে একটি Akka Streams ফ্লো উদাহরণ দেয়া হলো, যেখানে একটি লিস্টের ডেটা প্রসেস করা হবে:
import akka.actor.ActorSystem import akka.stream.{ActorMaterializer, Materializer} import akka.stream.scaladsl.{Source, Flow, Sink} object AkkaStreamsExample { def main(args: Array[String]): Unit = { implicit val system: ActorSystem = ActorSystem("AkkaStreamsSystem") implicit val materializer: Materializer = ActorMaterializer() // Define a Source val source = Source(List(1, 2, 3, 4, 5)) // Define a Flow (a transformation step) val flow = Flow[Int].map(x => x * 2) // Define a Sink (where data will end up) val sink = Sink.foreach[Int](println) // Connect Source -> Flow -> Sink source.via(flow).to(sink).run() } }এখানে:
Source: এটি একটি ডেটা স্ট্রিম তৈরি করে (এখানে একটি লিস্ট)।Flow: এটি একটি ট্রান্সফর্মেশন স্টেপ, যা ডেটাকে প্রসেস করে (এখানে ইনপুট ভ্যালুকে দ্বিগুণ করা হচ্ছে)।Sink: এটি ডেটা গ্রহণ করে এবং আউটপুট হিসেবে প্রিন্ট করে।
Backpressure:
Akka Streams backpressure মেকানিজম ব্যবহার করে, যা নিশ্চিত করে যে ডেটা স্ট্রিমিংয়ের গতি বজায় থাকবে এবং অতিরিক্ত ডেটা প্রসেসিং এড়ানো যাবে। এটি স্ট্রিমের অবস্থা এবং গতির উপর নির্ভর করে ডেটার সাইজ এবং আউটপুট নিয়ন্ত্রণ করতে সাহায্য করে।
৩. Akka HTTP এবং Streams একত্রে ব্যবহার
Akka HTTP এবং Akka Streams একত্রে ব্যবহার করে আপনি রিয়েল-টাইম ডেটা স্ট্রিমিং এবং HTTP সার্ভার তৈরি করতে পারেন। নিচে একটি উদাহরণ দেয়া হলো, যেখানে HTTP রিকোয়েস্টের মাধ্যমে ডেটা স্ট্রিম করা হয়:
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Source, Sink, Flow}
object AkkaHttpStreamExample {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("AkkaHttpStreamSystem")
implicit val materializer = ActorMaterializer()
val route =
path("stream") {
get {
val source = Source(List("one", "two", "three"))
val flow = Flow[String].map(str => s"Item: $str")
val sink = Sink.foreach[String](println)
// Connect Source -> Flow -> Sink
source.via(flow).to(sink).run()
complete("Streaming Started!")
}
}
Http().newServerAt("localhost", 8080).bind(route)
println("Server started at http://localhost:8080/stream")
}
}এখানে:
Sourceথেকে ডেটা স্ট্রিম করা হচ্ছে, যা HTTP রিকোয়েস্টে ব্যবহৃত হবে।Flowডেটার ট্রান্সফর্মেশন করছে, যেমন ডেটাকে স্ট্রিং হিসেবে প্রক্রিয়া করা হচ্ছে।Sinkডেটাকে প্রিন্ট করছে।
সারাংশ
- Akka HTTP হল একটি শক্তিশালী HTTP ফ্রেমওয়ার্ক যা ওয়েব সার্ভার এবং ক্লায়েন্ট তৈরি করতে ব্যবহৃত হয়।
- Akka Streams হল একটি reactive streams লাইব্রেরি, যা ডেটা স্ট্রিমিংয়ের জন্য ব্যবহৃত হয় এবং backpressure নিয়ন্ত্রণ করে।
- এই দুটি একত্রে ব্যবহার করে আপনি **রিয়েল-টাইম ডেট
া স্ট্রিমিং** এবং HTTP সার্ভিস তৈরি করতে পারেন। Akka HTTP এবং Akka Streams স্কালার শক্তিশালী টুল যা আপনাকে scalable, reactive, এবং efficient ডেটা প্রসেসিং সিস্টেম তৈরি করতে সহায়তা করে।
Read more