วันเสาร์ที่ 12 ธันวาคม พ.ศ. 2558

ws part 7 Server API example

>> HTTP methods ที่เพื่อนๆรู้จักกันแล้ว อาทิเช่น @GET เพื่อขอ resource, @PUT เพื่อ update resource, @POST เพื่อสร้าง resource และ @DELETE เพื่อลบ resource, เหล่านี้จะยกตัวอย่างการใช้งานตามโอกาสครับ

>> @Produces ง่ายๆเลย มันมีหน้าที่กำหนด output ของเมธอดบริการนั้นว่าจะให้ผลลัพธ์เป็นรูปแบบ (MIME types) อะไร มีได้มากกว่าหนึ่งรูปแบบ เช่น application/xml หรือ application/json หรือทั้งสองอย่างหรือมากกว่า, มันสามารถวางไว้ได้สองตำแหน่งครับ

1) ตำแหน่ง class-level หมายถึง นำ @Produces นี้ไปเขียนไว้ก่อนประกาศคลาสหรือ resource จะส่งผลให้เมธอดบริการภายใต้ resource นี้ทั้งหมดมี MIME types ตามที่กำหนดนี้เป็น default

2) ตำแหน่ง method-level หมายถึง นำ @Produces นี้ไปเขียนไว้ก่อนประกาศเมธอดหรือบริการ จะส่งผลให้เฉพาะเมธอดบริการนี้มี MIME types ตามที่กำหนด หรือกล่าวว่ามันจะไป override @Produces ของตำแหน่ง class-level ครับ

>> เมื่อมีการผลิตก็ต้องมีการบริโภค @Consumes มีไว้เพื่อบอกว่าเมธอดบริการนั้นๆสามารถรับ input จากฝั่งผู้ใช้บริการรูปแบบใดบ้าง เช่น post เข้ามาในรูปแบบ form หรือแบบ json หรือแบบ xml หรืออื่นๆ (ได้มากกว่าหนึ่งรูปแบบ โดยเลือกตามลำดับที่เรากำหนด), สามารถวางไว้ได้สองตำแหน่ง

1) ตำแหน่ง class-level
2) ตำแหน่ง method-level

ให้ผลลักษณะเดียวกับของ @Produces เพียงเปลี่ยนจากให้ output เป็นรับ input

>> จากตัวอย่างที่ผ่านมาเมื่อผมต้องการที่อยู่ของผู้ใช้ id เท่ากับ 001 หรือ 002 จะระบุเข้าไปที่ address url ดังนี้

../users/addresses/001 หรือ
../users/addresses/002

เจ้า 001 และ 002 คือ id แสดงว่าเราต้องมีวิธีการที่จะดึง id ข้างต้นออกจาก address url, ฮีโร่หรือผู้ช่วยเหลือในเรื่องนี้ก็คือ Parameter annotations ครับ ได้แก่
- @PathParam
- @QueryParam
- @MatrixParam
- @HeaderParam
- @CookieParam
- @FormParam
- @BeanParam

ครั้นจะมาอธิบายหน้าที่ของพวกมันในคราวเดียวก็ยังไงอยู่ เป็นว่าเราได้ใช้ตัวไหนจากตัวอย่างเช่นไร เราค่อยมาคุยรายละเอียดของพวกมันตัวนั้นๆกันนะครับ (แอบขี้เกียจ)

@Path("/{userId}")
@Produces(MediaType.APPLICATION_XML)
@GET
public Response getAddressesByUserId(@PathParam("userId") String userId) { ... }

โด้ดนี้เราได้เขียนกันไปแล้ว อธิบายได้ว่า
- เมธอด getAddressesByUserId นี้คือ subresource method นั่นเพราะมันมี @Path และ @GET HTTP method ระบุเอาไว้ (หากไม่มี HTTP methods ใดๆระบุไว้แต่มี @Path เมธอดลักษณะนี้มักคืนค่าเป็น resource หรือคลาสอื่น ซึ่งเราจะเรียกว่า subresource locator)
- หลังจาก ../users/addresses ก็คือ /{userId} หรือก็คือค่า input ที่ถูกส่งเข้ามาโดยใช้ @PathParam เป็นตัวรับ โดยชื่อจะต้องเหมือนกันกับใน @Path และรับเข้ามาให้ตัวแปร (พารามิเตอร์) อะไรนั้นก็ตามสะดวก ในที่นี้ก็ตั้งชื่อเดียวกัน นั่นคือ userId
- เมธอดนี้ผลิต (produce) ผลลัพธ์รูปแบบ MIME type เป็น xml ครับ

>> ตามประสามือใหม่ก็ต้องหัดจากตัวอย่างที่ง่ายและเป็นพื้นฐาน หลังจากนั้นจึงค่อยเพิ่มระดับความซับซ้อนเข้าไปทีละน้อย โอกาสนี้ผมขอใช้ตัวอย่างจากเว็บ

- http://javapapers.com/java/java-restful-web-services-with-json-and-jersey/

มาดัดแปลงแก้ไขพร้อมเพิ่ม layer เข้าไปอีกชั้นสองชั้น
- ให้เว็บเซอร์วิสมีความสามารถในการบริการดังนี้ แสดงรายการสินค้าทั้งหมด, เพิ่มสินค้าได้, ปรับปรุงรายละเอียดของสินค้าทีละชิ้นได้ และลบสินค้าทีละชิ้น ความคิดนี้คือ CRUD นั่นเอง
- ให้เว็บเซอร์วิสมีชั้นของ service และ dao เพื่อที่ root-resource จะเรียกชั้นของ service และชั้นของ service ไปเรียกชั้นของ dao โดยชั้นของ dao สมมติว่าติดต่อกับฐานข้อมูล
- โดยทั่วไปแล้วชั้นของ service และ dao มักถูก inject โดยกลไกอื่นแค่ครั้งเดียวและออบเจ็กค์เดียว ในที่นี้จึงขอใช้ static มาจัดการเพียงชั้นของ service ครับ
- โครงสร้างของ Server API

- จาร์ทั้งหมดที่ใช้

- root-resource


- ชั้นของ service ส่วนของ interface

- ชั้นของ service ส่วนของ implementation

- ชั้นของ dao ส่วนของ interface

- ชั้นของ dao ส่วนของ implementation



>> ทีนี้ก็มาทดสอบกัน โดยการใช้จาวาโปรเจ็กค์ธรรมดายิงเข้าไปขอใช้บริการ (เว็บเซอร์วิส: หลังบ้านคุยหลังบ้าน)
- จาร์ทั้งหมดและที่เพิ่มเข้ามาครับ

- pojo หรือจาวาคลาสธรรมดา โครงสร้างของมันนี้ฝั่งผู้ใช้บริการและฝั่งผู้ให้บริการต้องมีเหมือนกัน

- โค้ดทดสอบ ขอดูรายการสินค้าทั้งหมด, เพิ่มสินค้ารหัส 1002 หนึ่งชิ้น, ปรับปรุงชื่อสินค้ารหัส 1001 จาก iPhone 6s เป็น iPhone 6s plus!, ลบสินค้ารหัส 3003 และขอดูรายการสินค้าทั้งหมดอีกครั้ง


- สุดท้ายมาดู console ฝั่งผู้ให้บริการ (เว็บเซอร์วิส) ว่าเป็นอย่างไรเมื่อฝั่งผู้ใช้บริการขอใช้บริการครับ


>> อ่านข้อมูลเพิ่มเติม
- https://jersey.java.net/documentation/latest/message-body-workers.html
- https://jersey.java.net/documentation/latest/media.html#json.jackson

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

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