เซสชันฝั่งเซิร์ฟเวอร์ละเมิด REST หรือไม่


14

ตามรอยฟีลดิง (หนึ่งในผู้เขียนหลักของสเปค HTTP) ในรูปแบบสถาปัตยกรรมวิทยานิพนธ์ของเขาเมื่อพูดถึงส่วนที่เหลือเขากล่าวถึง:

[E] การร้องขอจากลูกค้าไปยังเซิร์ฟเวอร์ต้องมีข้อมูลทั้งหมดที่จำเป็นเพื่อทำความเข้าใจคำขอและไม่สามารถใช้ประโยชน์จากบริบทที่จัดเก็บไว้บนเซิร์ฟเวอร์

โดย "บริบทที่เก็บไว้" เขาอ้างถึงสถานะแอปพลิเคชันเช่นหมายเลขหน้าของหน้าถัดไปคือเทียบกับสถานะของทรัพยากรเช่นแหล่งข้อมูลใด ๆ รูปภาพ ฯลฯ - ซึ่งเป็นจุดรวมของ REST

มันยุติธรรมหรือไม่ที่จะบอกว่าความพยายามส่วนใหญ่ในการพักผ่อนที่บริสุทธิ์ (ต่อไปนี้เป็นการนำไปปฏิบัติซึ่งสอดคล้องกับวิทยานิพนธ์ข้างต้น) ต้องล้มเหลวเนื่องจากการพึ่งพาการจัดเก็บข้อมูลเซสชันบนเซิร์ฟเวอร์ (ถาวรหรืออย่างอื่น)?

แนวคิดของเซสชั่นเป็นเรื่องปกติ - โดยเฉพาะอย่างยิ่งสำหรับนักพัฒนาเว็บ - แต่มันสงบตามข้อกำหนดข้างต้นหรือไม่


2
ฉันจะพูดตามคำจำกัดความที่จริงแล้วไม่มีอะไรสงบ แต่ความหมายนั้นมีเหตุผลแม้เหตุผล? ลองนึกภาพการค้นหา google แบบ "พักผ่อน" ซึ่งคุณจะต้องจัดทำดัชนีของอินเทอร์เน็ตในคำขอของ Google เพื่อทำการค้นหาให้คุณ อะไร? ไม่การบอกว่าคุณไม่สามารถมีร้านขายสินค้าติดตัวได้และมีความสงบนิ่งจะเท่ากับการบอกว่าส่วนต่อประสานที่สงบเงียบนั้นไม่มีประโยชน์จริง ๆ แต่นั่นไม่ได้หมายความว่าเราทุกคนควรจะเริ่มต้นการรักษาการประชุมในหน่วยความจำและบอกว่ามันยังคงการออกแบบส่วนที่เหลือดี ...
จิมมี่ฮอฟฟา

3
ฉันคิดว่าควรสังเกตว่ามีความแตกต่างระหว่างสถานะแอปพลิเคชันและสถานะทรัพยากร (ดัชนีของ Google จะเป็นสถานะของทรัพยากรและถูกต้องตามกฎหมายอย่างสมบูรณ์) ฉันควรทำให้ชัดเจนยิ่งขึ้นในคำถาม
แมตต์

มีความแตกต่างเช่นนี้หรือไม่? กรุณากำหนดมัน :) ฉันเคยเห็นผู้คนพยายามที่จะนิยามสิ่งเหล่านี้มาก่อน แต่มันก็ดูเลือนจริงเพราะพวกเขาไม่ได้แตกต่างกัน พวกเขาทั้งคู่เป็นข้อมูลที่เปลี่ยนแปลงไม่ได้ความแตกต่างที่เกี่ยวข้องเพียงอย่างเดียวระหว่างรัฐในรูปแบบหนึ่งกับอีกรูปแบบหนึ่งคือไม่ว่าจะเป็นแบบถาวรหรือไม่ซึ่งรูปแบบที่ไม่ได้หมายความว่ามันมักจะสามารถสร้างใหม่ได้
Jimmy Hoffa

1
ฉันสงสัยตัวเอง เนื่องจากไม่มีใครอธิบายได้ว่าทำไมแอปพลิเคชันของฉันควรต้องการดาว "เงียบสงบ" อย่างใดอย่างหนึ่งฉันจึงไม่ต้องกังวลกับมันเลย
psr

คำตอบ:


10

ฉันจะบอกว่าใช่สถานะเซสชันทำให้แอป RESTful ไม่ใช่ RESTful ตัวอย่างเล็กน้อยน้องสาวของฉันสมัครเป็นสมาชิกกับ Wall Street Journal เป็นประจำเธอจะอ่านอะไรบางอย่างที่อยู่เบื้องหลัง paywall และตัดสินใจที่จะส่งลิงค์ (ผ่านไคลเอนต์อีเมลของเธอเองไม่ใช่ผ่าน WSJ) ให้เพื่อนที่ไม่มีบัญชี WSJ คลิกส่งล้มเหลว เห็นได้ชัดว่าประสบการณ์ของพี่สาวใน URL นั้นแตกต่างจากเพื่อนของเธอ

ที่เกี่ยวข้อง แต่ไม่เคร่งครัดในหัวข้อ:ฉันอยู่ในช่วงเริ่มต้นการออกแบบของแอปพลิเคชันที่ออกแบบมาเพื่อสนับสนุนการวิจัยที่สำคัญในเน็ต (เรียกว่าเควส (คิดว่า: บุ๊กมาร์กบนเตียรอยด์และ LSD) เจ้าของเควสต์ต้องการแชร์มุมมองเฉพาะของข้อมูลของเขา / เธอกับคนอื่น แต่มุมมองนี้ต้องการการรวมกันของสถานะ UI (เช่นการสร้างภาพข้อมูลที่แสดงข้อมูลใดในบานหน้าต่าง) พร้อมสิทธิ์ที่เหมาะสมในการเข้าถึง UI และข้อมูลที่แสดง มีสถานะการจัดเก็บจำนวนมากที่ผู้รับต้องใช้เพื่อรับมุมมองที่ต้องการ

วิธีการแก้ปัญหาปัจจุบันของฉันคือการเก็บทั้งหมดของ UI / ACL / สิ่งข้อมูลที่จำเป็นสำหรับมุมมองในวัตถุที่แยกต่างหากและกลับ URL ที่ (อาจจะเป็น UUID) สำหรับที่วัตถุ ฉันเชื่อว่าการเข้าถึงวัตถุมุมมองนั้นถือว่าสงบในแง่ที่ว่าทุกคนที่ครอบครองมันจะได้รับข้อมูล / ประสบการณ์เดียวกัน


1
คุณกำลังดูตัวอย่างวัตถุเป็นอีกมุมหนึ่งของสิ่งนี้ เรียบร้อย
แมตต์

การยอมรับสิ่งนี้เป็นคำตอบแม้จะมีคำตอบที่ยอดเยี่ยมอื่น ๆ ส่วนใหญ่เป็นเพราะมันตอบคำถามโดยตรงและให้ตัวอย่างที่ชัดเจนมาก นอกจากนี้ส่วนที่สองของวัตถุมุมมองจะเอียงตาชั่ง
แมตต์

1
หากคุณกำลังบอกว่าเว็บไซต์ wsj เป็นตัวอย่างของแอปที่ไม่สงบฉันจะไม่เห็นด้วยกับตัวอย่างที่แสดงให้เห็นว่า หากไซต์ WSJ นั้นเป็นตัวอย่างที่อาศัยข้อมูลที่ลูกค้าของน้องสาวของคุณมอบให้กับเธออย่างสมบูรณ์ข้อมูลนั้นเป็นไปตามคำนิยามที่ @Matt ให้ไว้ RESTful อย่างไรก็ตามหากขึ้นอยู่กับสถานะเซสชันในหน่วยความจำชั่วคราวเป็นไปตามนิยามที่ Matt ระบุว่าไม่สงบ ฉันแค่ชี้ประเด็นนี้เพราะคำจำกัดความของ Matt ที่ให้นั้นขึ้นอยู่กับการใช้งานเฉพาะขณะที่ REST นั้นถูกกำหนดโดยเทคนิคการบริโภคที่ดีกว่า
จิมมี่ฮอฟฟา

@JimmyHoffa - ความเข้าใจของฉันของข้อ จำกัด ของส่วนที่เหลือก็คือว่ามันไร้สัญชาติ นั่นดูเหมือนจะไม่น่าสงสัยสำหรับฉัน
Peter Rowell

หากแอปพลิเคชัน WSJ ไม่มีสถานะจะต้องส่งบทความที่ดูได้โดยลูกค้า ผู้ดูแลไซต์สามารถแก้ไขบทความนั้นได้ตลอดเวลาโดยไม่ผิดพลาดเพราะเป็นส่วนหนึ่งของสถานะแอป WSJ ฉันคิดว่าความแตกต่างที่พยายามอย่างหนักคือมันเป็นสถานะถาวรดังนั้นมันจะมีหลักประกันมากขึ้นและมีค่าใช้จ่ายในการจัดการน้อยกว่าสถานะที่ไม่สามารถใช้งานได้เช่นเซสชันพร้อมกับการควบคุมอะตอมมิกซิตี้ที่ง่ายขึ้นในการทำธุรกรรม พร้อมกับรูปแบบการบริโภคที่เรียบง่ายนี้เป็นสิ่งที่ผู้คนต้องการพักผ่อน (ฉันคิดว่า)
จิมมี่ฮอฟฟา

2

เซสชันฝั่งเซิร์ฟเวอร์ละเมิด REST หรือไม่

พวกเขาทำอย่างแน่นอน! เมื่อคุณใช้ REST จะต้องไม่มีเซสชันฝั่งเซิร์ฟเวอร์มิฉะนั้นคุณจะมีโซลูชัน RPC / REST แบบไฮบริด

ลูกค้าจะต้องส่งไปยังบริการ RESTful บริบททั้งหมดที่จำเป็นในการให้บริการคำขอรวมถึงข้อมูลที่จำเป็นในการรับรองความถูกต้องของลูกค้าทุกครั้งที่มีการร้องขอใหม่ เซิร์ฟเวอร์มีอิสระในการแคชข้อมูลเพื่อให้บริการตามมาได้เร็วขึ้น แต่ข้อมูลที่แคชจะต้องไม่รวมอยู่ในเซสชันฝั่งเซิร์ฟเวอร์ กล่าวอีกนัยหนึ่งคำขอนั้นจะต้องมีข้อมูลเพียงพอที่จะดำเนินการแม้ในกรณีที่ไม่มีสถานะแคช


1

อาจขึ้นอยู่กับสิ่งที่คุณหมายถึงโดย "ข้อมูลเซสชั่น" นั่นเป็นคำที่แม่นยำใช่ไหม

การสื่อสารที่ปลอดภัยระหว่างสองฝ่ายมักเกี่ยวข้องกับเซิร์ฟเวอร์ในการสร้าง (และจัดเก็บ) "โทเค็นการเข้าถึง" แบบ จำกัด เวลาซึ่งลูกค้าต้องจัดหาให้พร้อมกับคำขอแต่ละรายการเป็นวิธีการอนุญาต โทเค็นการเข้าถึงนี้มีอยู่แล้วในสิ่งที่ฉันเรียกว่า "ข้อมูลเซสชัน" - มันถูกเก็บไว้ที่ฝั่งเซิร์ฟเวอร์, จำกัด เวลาและเกี่ยวข้องกับลูกค้ารายหนึ่ง (โดยปกติคือสิทธิ์ของเขา)

ฉันจะแปลกใจมากถ้าการดำเนินการชนิดนี้ถูกระบุว่าไม่สงบ OAuth เป็นตัวอย่าง

ฉันไม่ใช่ผู้เชี่ยวชาญและฉันไม่มั่นใจมากที่นี่ ฉันแค่แบ่งปันข้อมูลเชิงลึกของฉันโดยหวังว่าพวกเขาจะมีประโยชน์


1

จุดที่สำคัญที่สุดของ REST คือ URI ที่ไปยัง ressource ชี้ไปที่ ressource เดียวกันเสมอ ดังนั้นผู้ใช้สามารถส่งต่อการอ้างอิงไปยังแหล่งข้อมูลนี้และทุกคนจะเห็นสิ่งเดียวกัน สิ่งนี้เรียกว่า Representational State Transfer (REST) หากเซิร์ฟเวอร์รักษาสถานะและมอบ ressource อื่นสำหรับ URI เดียวกันฉันจะบอกว่านี่ไม่ใช่ REST บริสุทธิ์อีกต่อไป


ไม่จำเป็นต้องเป็นความจริงที่ผู้ใช้จะเห็นสิ่งเดียวกัน .. การเข้าถึงสามารถกำหนดได้ว่าผู้ใช้คนใดคนหนึ่งจะเห็น
Erik

@Erik แต่ผู้ใช้จะระบุจำนวนที่พวกเขาต้องการเห็นในคำขอ (รวมถึงการใช้ Accept Header) ดังนั้นคำตอบของ Puckl ก็ถือเป็นจริง
Johan

1
@Johan ฉันจะส่งคืนข้อมูลที่แตกต่างกันสำหรับผู้ใช้ที่แตกต่างกันจากปลายทางเดียวกัน มิฉะนั้นสิ่งที่เป็นจุดของการตรวจสอบผู้ใช้
Erik

@ เอริคฉันก็จะทำเช่นนั้น ไม่มีน้อยฉันเชื่อว่าการรับรองความถูกต้องอยู่นอกสถานะของทรัพยากรดังนั้นพูดอย่างเคร่งครัดหากมุมมองได้รับผลกระทบจากผู้ใช้รับรองความถูกต้องแล้วมันจะไม่สงบ บางทีหากคุณต้องการตรา RESTful ของคุณคุณควรสร้าง "มุมมอง" ของทรัพยากรหลายรายการโดยขึ้นอยู่กับว่าใครเป็นผู้ร้องขอการเข้าถึงมันอนุญาตการเข้าถึงเฉพาะบางมุมมองเท่านั้น ดังนั้นสาธารณะอาจเข้าถึง / userprofiles / {userID} / publicview และผู้ใช้ได้รับการเข้าถึง / userprofiles / {userID} / fullprofile และเพื่อนที่ได้รับอนุญาตเข้าถึง / userprofiles / {userID} / friendsview
Johan

0

โดยทั่วไปเซสชันจะใช้เพื่อเพิ่มสถานะให้กับแอปพลิเคชันที่ไร้สัญชาติและเงียบสงบ ดังนั้นอย่างเป็นทางการสิ่งนี้ทำให้แอปพลิเคชัน RESTful ของคุณเป็นสถานะอย่างไรก็ตามการมีเซิร์ฟเวอร์ให้สถานะทำให้ชีวิตของคุณง่ายขึ้นเล็กน้อยเนื่องจากคุณไม่จำเป็นต้องส่งข้อมูลทั้งหมดไปมาในแต่ละคำขอ / การตอบกลับ

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

ดังนั้นในขณะที่มันเป็นการละเมิดคำจำกัดความของ REST อย่างเป็นทางการมีประโยชน์มากที่จะเห็นแอปพลิเคชัน RESTful ที่ไม่ได้ใช้สถานะผ่านทางเซสชัน


ฉันไม่เห็นด้วย. คุณมีเว็บไซต์ช็อปปิ้งที่ให้คุณกรองตามแบรนด์สีและขนาด เว็บไซต์ 1.0 แบบดั้งเดิมของเว็บจะจัดการกับสิ่งนี้ด้วยบางช่องทำเครื่องหมายเซสชันของฝั่งเซิร์ฟเวอร์และ POST หากฉันต้องการแชร์ลิงก์ไปยัง example.org/shirts ผู้คนจะไม่เห็นว่าฉันเลือก Medium, Black และ Roots (สิ่งนี้ยังทำให้ข้อความ "คุณกำลัง rePOSTing ข้อมูล" ที่น่าเกลียดเมื่อคุณคลิกกลับ) แต่ถ้าฉันแชร์ลิงค์ไปยัง (เช่น) example.org/shirts/medium-black-roots ทุกคนมีการแสดงที่เหมือนกัน ข้อมูลสถานะที่จำเป็นทั้งหมดอยู่ใน URL (หรือเนื้อหาของ POST หากจำเป็น แต่คุณไม่สามารถแบ่งปันได้)
Jesse Buchanan

... สงบอาจไม่เหมาะกับทุกสิ่ง ทรัพยากรแอปพลิเคชันของคุณเป็นไปตามสมมุติฐานหรือไม่ บางทีมันอาจจะไม่เหมาะกับ RIA ที่มีสถานะเป็นจำนวนมากซึ่งไม่ใช่ทรัพยากร ฉันไม่สามารถนึกถึงตัวอย่างที่ดีใด ๆ ที่จะซื่อสัตย์
Jesse Buchanan

0

สิ่งที่ฟีลดิงหมายถึงโดยคำสั่งนั้นคือแอปพลิเคชันเซิร์ฟเวอร์ที่โฮสต์ REST API ไม่ได้เชื่อมโยงสถานะโดยรอบกับการร้องขอโดยกลไกเบื้องหลัง พิจารณาความแตกต่างระหว่างนั้นแอพพลิเคชันเซิร์ฟเวอร์และเซิร์ฟเวอร์ฐานข้อมูล ข้อ จำกัด ส่วนที่เหลือคือแอพพลิเคชันเซิร์ฟเวอร์ควรจะไร้สัญชาติ อย่างไรก็ตามแอ็พพลิเคชันเซิร์ฟเวอร์สามารถมอบหมายการร้องขอสถานะทรัพยากรไปยังเซิร์ฟเวอร์ฐานข้อมูลตามข้อมูลที่เป็นส่วนหนึ่งของคำขอเช่นการรวมผู้ใช้ / รหัสผ่านในส่วนหัวการอนุญาตหรือ Uri เอง ท้ายที่สุด REST ขึ้นอยู่กับรุ่นของไคลเอ็นต์ / เซิร์ฟเวอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.