Friday, August 04, 2006

Tapestry Asset

Asset ในความหมายที่ Tapestry ใช้ ก็คือ binary หรือ text file ที่ browser ต้องการใช้
ไม่ว่าจะเป็น image file, javascript file, css file ฯลฯ

การที่ Tapestry define Asset ออกมาเป็นเรื่องเป็นราวแบบนี้
อย่างน้อยก็ช่วยให้เราจัดการกับ Resource File ได้ง่ายขึ้น
เช่นแทนที่จะยุ่งกับ physical file โดยตรง ก็ไปจัดการผ่าน Logical file แทน
ทำให้จัดการเรื่องพวก internationalize ได้ง่ายขึ้น
(พวกเปลี่ยนรูปที่แสดง ตาม locale ของ user)
รวมทั้งทำเรื่อง dynamic asset ณ runtime ได้ง่ายขึ้น

Tapestry แบ่งที่มาของ Asset ออกเป็น 2 ประเภทคือ
  • Context Asset
    asset ที่อยู่ใน Context Directory ของ Web application
  • Classpath Asset
    asset ที่อยู่ใน classpath ไม่ว่าจะเป็นใน WEB-INF/classes หรือใน jar ต่างๆ

asset ประเภท Context Asset ถือเป็นเรื่องปกติธรรมดาอยู่แล้วไม่มีประเด็นให้พูดถึง
แต่ asset ประเภท classpath นี่สิ มีประโยชน์มากในแง่ของการ reuse
เพราะช่วยให้เราเขียน component เป็น module (ภายในมีทั้ง html, gif, javascript, ฯลฯ)
ที่นำมาใช้ใหม่ได้่ง่าย

การเข้าถึง Classpath Asset จะทำผ่าน AssetService
โดย url ที่ใช้เข้าถึงจะมีหน้าตาแปลกๆแบบนี้

http://localhost:8080/fin/app?digest=ff8e3332b16d745764befd7c6956ad9a&path=%2Fwcf%2Fweb%2Fjs%2Fwcfutil.js&service=asset

สังเกตว่ามี parameter ที่ชื่อ digest อยู่ด้วย
ทำไมต้องมีค่า digest ด้วย?

มูลเหตุที่ต้องมี digest แปะมา ก็เพื่อป้องกันไม่ให้ผู้ไม่หวังดี
ใช้ service นี้ไปดึงเอาพวก class file ออกมาตามใจชอบ
(เนื่องจาก service นี้สามารถดึงเอาอะไรก็ได้ที่อยู่ใน classpath)

ประเด็นหนึ่งของการมี checksum แปะแบบนี้ก็คือ
มันจะกิน cpu time ทุกครั้งที่มีการ request asset นี้
Tapestry ก็เลยออกแบบให้มี cache ในส่วน generate digest

ผลพลอยได้ที่มาโดยไม่ตั้งใจ ก็คือ เมื่อเนื้อหา file เปลี่ยน
ค่า digest ก็จะเปลี่ยนไปได้วย (แต่ต้อง clear cache ก่อน)
ทำให้เราไม่เจอปัญหาเรื่อง browser cache
(เหมือนกับที่ rails generate timestamp แปะท้าย url
ที่ request ขอ javascript ก็เพื่อป้องกันปัญหานี้เหมือนกัน)

ปัญหาของการมี digest อีกอย่างก็คือ
link ทุก link ต้องเกิดจากการ generate ของ server
(เพราะ server จะต้องแปะค่า digest ให้)
ทำให้เราไม่สามารถใช้ javascript load ข้อมูลแบบ dynamic ได้
(dojo ใช้กลไกการ load แบบ dynamic)

เพื่อแก้ปัญหานี้ Tapestry4.1 ก็เลยมีการเพิ่ม feature UnprotectedAssets
เพื่อให้เราเลือก config ได้ว่า Asset กลุ่มไหนต้องมี Digest
กลุ่มไหนที่ไม่ต้องมี Digest

Related link from Roti

No comments: