[Java] ใช้ REST ให้ถูกต้องด้วย GET POST PUT DELETE
ก่อนหน้านี้ RESTful Web Service ด้วย Jersey เราได้มีการเขียนโดยมอง services แต่ละตัวเป็นชิ้นๆไป โดยเรียกใช้ผ่านชื่อและกำหนดเป็น GET หรือ POST
แต่....
นั่นยังไม่ใช่สิ่งที่ถูกต้อง ซึ่งผมเองก็ได้ Unlock Archivement videogame_asset หลังจากใช้งานไปซักพัก ซึ่งก็จะมา update ให้เข้าใจถูกต้องครับ
Concept ของ REST เค้าจะมองว่า Web Service 1 URL ทำงานได้หลากหลาย ซึ่งหมายถึง 1 URL ไม่ได้ผูกติดกับ 1 method อีกต่อไป
จะถูกใช้สำหรับ parameter คล้ายกับ @FormParam และ @QueryParam แตกต่างตรงที่ค่าจะถูกส่งมาในรูปแบบ path
แต่....
นั่นยังไม่ใช่สิ่งที่ถูกต้อง ซึ่งผมเองก็ได้ Unlock Archivement videogame_asset หลังจากใช้งานไปซักพัก ซึ่งก็จะมา update ให้เข้าใจถูกต้องครับ
Concept ของ REST เค้าจะมองว่า Web Service 1 URL ทำงานได้หลากหลาย ซึ่งหมายถึง 1 URL ไม่ได้ผูกติดกับ 1 method อีกต่อไป
@PathParam
จะถูกใช้สำหรับ parameter คล้ายกับ @FormParam และ @QueryParam แตกต่างตรงที่ค่าจะถูกส่งมาในรูปแบบ path
@POST @Override @Consumes(MediaType.APPLICATION_JSON) public void create(Person person) { dao.create(person); }
@GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Person find(@PathParam("id") Integer id) { return dao.find(id); }
@GET @Path("{from}/{to}") @Produces(MediaType.APPLICATION_JSON) public ListfindAgeInRange(@PathParam("from") Integer from, @PathParam("to") Integer to) { return dao.findAgeInRange(id); }
@PUT @Path("{id}") @Consumes(MediaType.APPLICATION_JSON) public void edit(@PathParam("id") Integer id, Person person) { dao.edit(person); } @DELETE @Path("{id}") public void remove(@PathParam("id") Integer id) { dao.remove(id); }
ตัวอย่างด้านบนทั้ง 3 รูปแบบจะถูกเรียกด้วย URL เดียวกัน ในขณะที่ http method ในการเรียกแตกต่างกันไป
แน่นอนว่าเราสามารถปรับ parameter ได้ตามสะดวก อาจเป็น condition อื่นๆ เช่น findAgeInRange() ก็จะต้องส่ง @PathParam มาให้ครบถ้วนด้วยครับ
สังเกตว่า มุมมองจะแตกต่างจากการสร้าง method โดยตั้งชื่อตามลักษณะการใช้งาน ถึงแม้ว่ามันสามารถออกมาเป็น web services เช่นเดียวกันแต่ REST มีมาตรฐานสากลที่เค้าเข้าใจตรงกันแบบนี้ครับ
นอกจากนี้ยังมีคำที่เค้าพูดถึงกันเมื่อต้อง design REST คือ
GET ปลอดภัย(safe) เพราะเป็นแค่การดึงข้อมูล ในขณะที่ POST PUT DELETE นั้นถือว่าไม่ปลอดภัย (unsafe)
สรุปแล้วผมมองว่าการเขียน REST ให้ถูกต้อง คือการออกแบบตามกฎที่ตกลงกัน ซึ่งจะทำให้คนมาใช้สามารถเข้าใจได้ง่ายกว่าการที่เราเขียนตามใจฉันแน่นอนครับ tag_faces
ref.
http://restcookbook.com/HTTP%20Methods/idempotency/
https://knpuniversity.com/screencast/rest/put-versus-post
http://www.restapitutorial.com/lessons/httpmethods.html http://www.tutorialspoint.com/http/http_methods.htm
http://SampleWeb/PeopleServices/ | |
---|---|
POST | เพิ่มข้อมูล |
http://SampleWeb/PeopleServices/99 | |
---|---|
GET | ดึงข้อมูลที่ id = 99 |
PUT | แก้ไขข้อมูลที่ id = 99 |
DELETE | ลบข้อมูลที่ id = 99 |
แน่นอนว่าเราสามารถปรับ parameter ได้ตามสะดวก อาจเป็น condition อื่นๆ เช่น findAgeInRange() ก็จะต้องส่ง @PathParam มาให้ครบถ้วนด้วยครับ
สังเกตว่า มุมมองจะแตกต่างจากการสร้าง method โดยตั้งชื่อตามลักษณะการใช้งาน ถึงแม้ว่ามันสามารถออกมาเป็น web services เช่นเดียวกันแต่ REST มีมาตรฐานสากลที่เค้าเข้าใจตรงกันแบบนี้ครับ
นอกจากนี้ยังมีคำที่เค้าพูดถึงกันเมื่อต้อง design REST คือ
Safe Method
หมายถึงการมองว่า http method ตัวไหนปลอดภัย ตัวไหนไม่ปลอดภัย ซึ่งคำว่าปลอดภัยในที่นี้หมายถึงว่ามีการเปลี่ยนแปลงกับข้อมูลหรือไม่GET ปลอดภัย(safe) เพราะเป็นแค่การดึงข้อมูล ในขณะที่ POST PUT DELETE นั้นถือว่าไม่ปลอดภัย (unsafe)
Idempotent
การทำงาน 1 หรือ 10 ครั้ง ให้ผลลัพธ์ที่เหมือนกัน ซึ่งใน reference เขายกตัวอย่างแบบนี้ครับa = 4; // idempotent a++; // non-idempotentมีเพียง POST เท่านั้นที่ไม่เข้าข่ายว่าเป็น idempotent เพราะเราจะใช้สำหรับ create/insert ข้อมูล ก็เป็นไปได้ที่จะเกิดการซ้ำซ้อนของข้อมูลเรื่อยๆ หรืออาจเกิดการชนกันกับข้อมูลเดิม ในขณะที่ GET PUT DELETE นั้นครั้งที่ 2 3 4 ... ก็ยังให้ผลลัพธ์เหมือนเดิม
ref.
http://restcookbook.com/HTTP%20Methods/idempotency/
https://knpuniversity.com/screencast/rest/put-versus-post
http://www.restapitutorial.com/lessons/httpmethods.html http://www.tutorialspoint.com/http/http_methods.htm