วันอาทิตย์ที่ 6 ธันวาคม พ.ศ. 2558

ws part 4 RESTful WS how to create subresource locators

>> ก็เพิ่งเริ่มต้นทำความรู้จักกับเว็บเซอร์วิส จับผิดจับถูกก็ถูไถไปตามตำราว่าไว้ บ้างก็ตำรายังไม่ได้กล่าวถึงก็ใจร้อนไปขอวิชาจากที่อื่นๆเสียก่อน ความเดิมจาก part ที่ผ่านมากะว่าจะสร้าง client เพื่อขอใช้บริการเว็บเซอร์วิส อื่ม ขออนุญาตถัดไปก่อนนะครับ ติดใจเรื่อง subresource locators

>> เกี่ยวกับ @Path เราทราบกันแล้วว่ามันวางได้สองตำแหน่ง
1) Class-level
2) API-level
class-level คือวาง @Path ไว้ ณ root-resource หรือก็คือ resource แรกที่เราต้องการเข้าถึงมันผ่าน uri หรือดังตัวอย่างที่ผ่านมานั่นแหละครับ ส่วน api-level ก็คือการวาง @Path ไว้ ณ subresource methods ที่อยู่ภายใต้ root-resource อีกที อื่ม ผมไม่งงนะ แต่ไม่แน่ใจว่าเข้าใจถูกไหม เข้าประเด็นคราวนี้กันเลยดีกว่า แล้ว subresource locators คืออะไร?

>> subresource locators ภาษาบ้านๆเลยก็คือเมธอดที่ไม่มี HTTP header resource methods ใดๆระบุไว้ คือไม่มีพวก @GET, @PUT, @POST, @DELETE อะไรอย่างนี้เขียนไว้น่ะ จะมีเพียง @Path ในระดับ api-level เท่านั้นที่กำกับเอาไว้ เพราะอะไรน่ะหรือ? เพราะว่า return type ของเมธอดดังกล่าวนี้จะ return คลาสที่เป็น resource ออกไปน่ะสิ

>> สมมติให้ user หนึ่งคนสามารถมีที่อยู่ได้ เราจะเรียก user ว่าเป็น root-resource จากนั้นจะไปตามหาที่อยู่ของเขาผ่าน subresource methods ก่อน โดยให้เจ้า subresource methods นี้คืนค่าออกมาเป็น resource อีกตัวหนึ่ง เราเรียกการ redirect จาก subresource methods ของ root-resource ใดๆไปยัง resource ตัวใหม่นี้ว่า subresource locators ครับ

>> จะสังเกตได้ว่าตอนนี้เราพอจะหยิบใช้ประดา annotation ได้หลายตัวแล้ว ไม่ว่าจะเป็น @Path, @Produces, @GET รวมถึง @XmlRootElement และเพื่อไม่ให้มือใหม่ (โดยเฉพาะผมเองนี่แหละ) ไม่สับสนจนเกินไป เราจะมาสร้างตัวอย่างง่ายๆเพื่อเรียกใช้ subresource locators กันครับ

>> สมมติโจทย์ว่า 1 user มีได้หลาย address เช่น ผมคนเดียวมีบ้านอยู่ที่กรุงเทพถึงสองหลัง เราจะให้ user เป็น root-resource และให้ address เป็น resource ที่ถูกเรียกโดยวิธีการ subresource locators
- จะมีสองคลาสที่เกี่ยวข้องกันดังนี้ user ถูกจัดการโดยคลาส UserResource และ address ถูกจัดการโดยคลาส AddressResource
- หากเรียกไปว่า ../users จะได้ข้อความ We are users!

- หากเรียกไปว่า ../users/addresses จะได้เป็น json ของรายการ user ทั้งหมดที่สมมติว่าเราได้เก็บไว้ในฐานข้อมูล

- และหากว่าเรียกไปยัง user id ใดๆ เช่น ../users/addresses/001 จะได้เป็น xml ของรายการที่อยู่ทั้งหมดของ user ที่มี id เป็น 001 ครับ



>> วิธีการออบแบบเว็บเซอร์วิส uri นี้ยังไม่ดีนักนะครับ โอกาสต่อๆไปเราควรได้พูดคุยกันบ้างถึงวิธีการ design ที่น่าจะดูดีมากกว่านี้ เอาล่ะ ลงมือได้

>> แรกเลย เรากำหนดให้เมธอด getAddresses ของคลาส UserResource กระทำ redirect ไปยัง resource เป้าหมาย นั่นคือคลาส AddressResource


>> คลาส AddressResource หรือ resource นี้มีบริการสองอย่าง หนึ่งคือ getAddresses จะให้ที่อยู่ทั้งหมดออกไป ส่วน getAddressesByUserId จะถามหา userId ใดๆที่เราจะต้องระบุมากับ uri ในที่นี้คือ ../users/addresses/001



>> เมื่อ subresource locators ข้างต้นถูกเรียก เราจะต้องเพิ่มจาร์ตัวนี้เข้ามาครับ มันคือ jersey-entity-filtering ไม่งั้นติด error

>> เมื่อพยายามส่งผลลัพธ์ (Response) กลับออกไปใสรูปของ List หากว่าเป็น json จะต้องเพิ่มจาร์ตัวนี้เข้าไป มันคือ jackson-module-jaxb-annotations


>> และเมื่อพยายามเปลี่ยนหรือต้องการส่งผลลัพธ์จาก List เป็น xml จะต้องห่อหุ้มหรือบอกว่าไส้ในของ List เป็นคลาสอะไร ให้ใช้คลาส javax.ws.rs.core.GenericEntity มาจัดการครับ ไม่งั้นติด page error 500

>> เย้ๆทำได้แล้ว แม้จะดูรกไปบ้างก็เถอะ เป็นว่า part ต่อไปเรามาพูดเรื่อง design กันหน่อยดีกว่านะ บายจ้า

>> ขอบคุณสำหรับความช่วยเหลือครับ
- http://stackoverflow.com/questions/11040995/a-message-body-writer-for-java-class-java-util-arraylist

ไม่มีความคิดเห็น:

แสดงความคิดเห็น