สปิ๊ฟฟี่...
Spiffy เป็นเฟรมเวิร์กเว็บที่ใช้ Scala, Akka (การใช้งานนักแสดง Scala) และ Java Servelet 3.0 API ใช้อินเทอร์เฟซแบบอะซิงก์และมีเป้าหมายเพื่อสร้างสภาพแวดล้อมแบบขนานและปรับขนาดได้ขนาดใหญ่สำหรับเว็บแอปพลิเคชัน ส่วนประกอบต่างๆ ของ Spiffy ล้วนมีพื้นฐานอยู่บนแนวคิดที่ว่าพวกเขาจำเป็นต้องเป็นโมดูลเรียบง่ายที่เรียบง่ายซึ่งทำงานจำนวนเล็กน้อยได้อย่างรวดเร็ว และส่งต่อคำขอไปยังส่วนประกอบถัดไปในไปป์ไลน์ หลังจากที่องค์ประกอบสุดท้ายเสร็จสิ้นการประมวลผลคำขอ มันจะส่งสัญญาณไปยังคอนเทนเนอร์เซิร์ฟเล็ตโดย "ดำเนินการ" คำขอให้เสร็จสิ้นและส่งกลับไปยังไคลเอนต์
เพิ่มเส้นทางบางส่วน:
// index page, no code, just text
"""^/$""".r -> "Welcome to Spiffy!",
// main news page
new Regex("""^/(news)/$""") -> NewsController(),
// view some news by id
new Regex("""^/(news)/(view)/(d+)/$""") -> NewsController()
เขียนตัวควบคุม:
def receive = {
// handles "news/add/"
case ControllerMsg(List("news", "save"), req, res, ctx) => {
// run validation on the request using Spiffy's validation DSL
var errors:Map[String, Set[String]] = validate (req) (
"email" as email confirmedBy "email_confirm",
"email_confirm" as email,
"title" as (string, 32),
"body" as string,
"tag" as string optional
) match {
case Some(List(errs,warns)) => { // Problem validating
errs
}
case None => None.toMap // passed validation
}
}
// handles "/news/"
case ControllerMsg(List("news"), req, res, ctx) => {
// load up news and stuff in map then render
val params = loadNews
view() ! ViewMsg("news", params, req, res, ctx)
}
// handles "/news/view/$newsId/"
case ControllerMsg(List("news", "view", newsId), req, res, ctx) => {
// usually you want to load the item, in this example we dont
// load item and set the params that the view will render
val news = loadNewsItem(newsId)
val params:Map[Any,Any] = Map("news" -> news)
// ask the view to render
view() ! ViewMsg("newsView", params, req, res, ctx)
}
}
จากนั้นสร้างเทมเพลตบางส่วน คุณสามารถค้นหาเพิ่มเติมเกี่ยวกับตัวอย่างนี้ได้โดยดูที่ NewsController และ SpiffyConfig
ในขณะนี้ เพื่อที่จะใช้ Spiffy คุณต้องสร้าง jar (mvn jar:jar) และเพิ่มลงใน classpath ของแอปพลิเคชันของคุณ คุณต้องกำหนดตัวแปรสภาพแวดล้อมต่อไปนี้ด้วย (context.xml จะทำ):
<Environment name="SpiffyConfigObject" value="org.spiffy.config.SpiffyBuiltinConfig" type="java.lang.String"/>
คุณต้องแทนที่ org.spiffy.config.SpiffyBuiltinConfig
ด้วยอ็อบเจ็กต์ที่ขยาย org.spiffy.config.SpiffyConfig
และจัดเตรียมค่าที่จำเป็นทั้งหมด ดู SpiffyConfig เป็นตัวอย่าง
สปิฟฟีอาศัยนักแสดงอัคก้าในการแบ่งส่วนและแยกองค์ประกอบต่างๆ ทั้งหมดออกจากกัน ทุกส่วนประกอบในไปป์ไลน์ Spiffy (ยกเว้นตัวกรองเริ่มต้น) ประกอบด้วยกลุ่มนักแสดง Akka นักแสดงที่เก่งกาจได้รับการสนับสนุนจากพูลบาลานซ์โหลดของผู้มอบหมายงานประเภทต่างๆ
Spiffy ถูกนำมาใช้เป็นตัวกรอง หลังจากที่ตัวกรองได้รับคำขอ มันจะทำให้มันอยู่ในโหมดอะซิงโครนัสและส่งไปยังเราเตอร์ จากนั้นเราเตอร์จะตัดสินใจว่าจะทำอย่างไรกับคำขอโดยตรวจสอบ URL คำขอและประเมินเทียบกับรายการการแมปตัวควบคุมที่รู้จัก การแมปคือนิพจน์ทั่วไปที่ตรงกับ URL ที่ร้องขอ และกำหนดให้กับคอนโทรลเลอร์ที่เกี่ยวข้อง หากพบการจับคู่ที่สำเร็จ เราเตอร์จะส่งข้อความไปยังคอนโทรลเลอร์พร้อมกับคำขอ (และวัตถุที่จำเป็นทั้งหมดที่จำเป็นต้องส่งไปพร้อมกับมัน) เมื่อถึงจุดนั้น งานของเราเตอร์ก็เสร็จสิ้น และสามารถประมวลผลคำขอที่เข้ามาใหม่ได้ฟรี หลังจากที่คอนโทรลเลอร์ได้รับการร้องขอแล้ว คอนโทรลเลอร์จะดำเนินการตามตรรกะที่ต้องการในคำขอและสามารถตัดสินใจยุติคำขอหรือส่งต่อไปยังส่วนประกอบอื่นของ Spiffy (โดยปกติคือตัวจัดการมุมมอง)
Spiffy ใช้แนวคิดของ hooks เพื่อแสดงลอจิกที่สามารถห่อหุ้มและรันก่อนและหลังส่วนประกอบบางอย่างของไปป์ไลน์ของเฟรมเวิร์ก Hooks สามารถรันก่อนและหลังคอนโทรลเลอร์และมุมมองได้ ฮุคที่จะทำงานก่อนที่คอนโทรลเลอร์จะตัดสินใจเลี่ยงผ่านคอนโทรลเลอร์โดยสิ้นเชิง หรืออาจเพียงดำเนินการตรรกะบางอย่าง เช่น การรับรองความถูกต้อง หรือแก้ไขคำขอก่อนที่คอนโทรลเลอร์จะมีโอกาสทำงานกับมัน ฮุคที่ทำงานหลังจากคอนโทรลเลอร์ยังสามารถกำหนดเส้นทางคำขอไปยังคอนโทรลเลอร์อื่น แก้ไข หรือยุติคำขอที่นั่น จากนั้นโดยการส่งคำขอกลับไปยังไคลเอนต์ ตรรกะเดียวกันนี้ถูกใช้ในมุมมองด้านหน้าและหลัง โดยที่ hook สามารถหยุดมุมมองจากการเรนเดอร์ทั้งหมด หรืออาจส่งเอาต์พุตที่เรนเดอร์ไปยังส่วนอื่นของเฟรมเวิร์กที่สามารถทำงานเพิ่มเติมบนเอาต์พุตที่เรนเดอร์ได้