คำถามติดแท็ก api-design

Application Programming Interface (API) การออกแบบกล่าวถึงแนวปฏิบัติที่ดีที่สุดสำหรับการสร้างไลบรารีสำหรับวัตถุประสงค์ทั่วไปหรือการใช้สาธารณะ

5
REST API เหมาะสำหรับโดเมนที่ใช้คำสั่ง / การดำเนินการอย่างไร
ในบทความนี้ผู้เขียนอ้างว่า บางครั้งจำเป็นต้องเปิดเผยการดำเนินการใน API ที่โดยทั่วไปจะไม่สงบ และนั่น หาก API มีการดำเนินการมากเกินไปนั่นเป็นข้อบ่งชี้ว่ามันได้รับการออกแบบด้วยมุมมอง RPC แทนที่จะใช้หลักการ RESTful หรือ API ที่เป็นปัญหานั้นเหมาะสมสำหรับรุ่นประเภท RPC โดยธรรมชาติ สิ่งนี้สะท้อนถึงสิ่งที่ฉันได้อ่านและได้ยินที่อื่นเช่นกัน อย่างไรก็ตามฉันพบว่ามันค่อนข้างสับสนและฉันต้องการทำความเข้าใจเกี่ยวกับเรื่องนี้ให้ดีขึ้น ตัวอย่างฉัน: การปิด VM ผ่านอินเตอร์เฟส REST ฉันคิดว่ามีสองวิธีที่แตกต่างกันในการสร้างแบบจำลองการปิดระบบของ VM แต่ละวิธีอาจมีรูปแบบต่างกันเล็กน้อย แต่เราจะมุ่งเน้นไปที่ความแตกต่างพื้นฐานที่สุดในตอนนี้ 1. แก้ไขคุณสมบัติสถานะของทรัพยากร PATCH /api/virtualmachines/42 Content-Type:application/json { "state": "shutting down" } (หรืออีกวิธีหนึ่งPUTบนทรัพยากรย่อย/api/virtualmachines/42/state) VM จะปิดระบบในพื้นหลังและในเวลาต่อมาขึ้นอยู่กับว่าการปิดเครื่องจะสำเร็จหรือไม่สถานะอาจได้รับการปรับปรุงภายในด้วย "ปิด" 2. ใส่หรือโพสต์บนคุณสมบัติการกระทำของทรัพยากร PUT /api/virtualmachines/42/actions Content-Type:application/json { "type": "shutdown" } …

5
คุณแสดงถึงการซิงค์แบบสองทิศทางใน REST api ได้ดีที่สุดอย่างไร
สมมติว่าระบบที่มีเว็บแอปพลิเคชันที่มีทรัพยากรและการอ้างอิงถึงแอปพลิเคชันระยะไกลที่มีทรัพยากรที่คล้ายกันอื่นคุณจะแสดงการดำเนินการซิงค์แบบสองทิศทางที่ประสานทรัพยากร 'ท้องถิ่น' กับทรัพยากร 'ระยะไกล' ได้อย่างไร ตัวอย่าง: ฉันมี API ที่แสดงรายการสิ่งที่ต้องทำ รับ / โพสต์ / วาง / ลบ / ลอส / ฯลฯ API นั้นสามารถอ้างอิงบริการสิ่งที่ต้องทำแบบรีโมต GET / POST / PUT / DELETE / todo_services / ฯลฯ ฉันสามารถจัดการ todos จากบริการระยะไกลผ่าน API ของฉันในฐานะตัวแทนผ่าน GET / POST / PUT / DELETE / todo_services / abc123 / …

2
รูปแบบที่ดีที่สุดสำหรับการเพิ่มไอเท็มที่มีอยู่ในคอลเล็กชันใน REST API คืออะไร
ฉันออกแบบ REST API ที่ใช้งานได้จริงและฉันติดอยู่กับวิธีเพิ่มเอนทิตีที่มีอยู่ในคอลเลกชัน โมเดลโดเมนของฉันมีโครงการที่มีไซต์ต่างๆ นี่เป็นความสัมพันธ์แบบกลุ่มต่อกลุ่มที่เข้มงวดและฉันไม่จำเป็นต้องสร้างเอนทิตีที่จำลองความสัมพันธ์อย่างชัดเจน (เช่น ProjectSite) API ของฉันจะช่วยให้ผู้บริโภคสามารถเพิ่มเว็บไซต์ที่มีอยู่ในโครงการ ที่ที่ฉันต้องวางสายคือข้อมูลเดียวที่ฉันต้องการจริงๆคือ ProjectId และ SiteId แนวคิดเริ่มต้นของฉันคือ: 1. POST myapi/projects/{projectId}/sites/{siteId} แต่ฉันก็คิดถึง 2. POST myapi/projects/{projectId}/sites ด้วยเอนทิตีของไซต์ที่ส่งเป็นเนื้อหา JSON ตัวเลือกที่ 1 นั้นง่ายและใช้งานได้ แต่รู้สึกไม่ถูกต้องและฉันมีความสัมพันธ์อื่น ๆ ที่ไม่สามารถทำตามรูปแบบนี้ดังนั้นมันจึงเพิ่มความไม่สอดคล้องกับ API ของฉัน ตัวเลือก 2 รู้สึกดีขึ้น แต่นำไปสู่ข้อกังวลสองข้อ: ฉันควรสร้างเว็บไซต์หรือส่งข้อยกเว้นหากมีการโพสต์ไซต์ใหม่ (SiteId = 0) เนื่องจากฉันต้องการเพียง ProjectId และ SiteId เพื่อสร้างความสัมพันธ์ไซต์อาจถูกโพสต์ด้วยข้อมูลที่ผิดหรือขาดหายไปสำหรับคุณสมบัติอื่น ๆ ตัวเลือกที่ 3 คือการจัดเตรียมจุดปลายอย่างง่ายเพียงอย่างเดียวสำหรับการสร้างและลบความสัมพันธ์ จุดสิ้นสุดนี้คาดว่าจะมี …
23 rest  api-design 

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

2
เราควรรู้อยู่เสมอว่า API กำลังทำอะไรโดยดูที่รหัส?
เมื่อเร็ว ๆ นี้ฉันได้พัฒนา API ของตัวเองและด้วยความสนใจลงทุนในการออกแบบ API ฉันมีความสนใจอย่างมากว่าฉันจะปรับปรุงการออกแบบ API ได้อย่างไร แง่มุมหนึ่งที่เกิดขึ้นสองสามครั้งคือ (ไม่ใช่โดยผู้ใช้ API ของฉัน แต่ในการสังเกตการอภิปรายเกี่ยวกับหัวข้อ): สิ่งหนึ่งที่ควรรู้เพียงแค่ดูรหัสที่เรียก API ว่ามันกำลังทำอะไรอยู่ ตัวอย่างเช่นดูการสนทนานี้ใน GitHub สำหรับวาทกรรมวาทกรรมมันมีลักษณะดังนี้: foo.update_pinned(true, true); เพียงแค่มองไปที่โค้ด (โดยไม่รู้ชื่อพารามิเตอร์เอกสาร ฯลฯ ) เราไม่สามารถเดาได้ว่ามันจะทำอะไร - อาร์กิวเมนต์ที่ 2 หมายถึงอะไร การปรับปรุงที่แนะนำคือการมี: foo.pin() foo.unpin() foo.pin_globally() และนั่นก็เป็นการล้างสิ่งต่าง ๆ (ข้อโต้แย้งที่สองคือว่าจะตรึง foo ทั่วโลกฉันเดา) และฉันเห็นด้วยในกรณีนี้ภายหลังจะเป็นการปรับปรุงอย่างแน่นอน แต่ผมเชื่อว่าอาจจะมีกรณีที่วิธีการในการตั้งค่าสถานะที่แตกต่างกัน แต่ที่เกี่ยวข้องเหตุผลจะได้รับการสัมผัสที่ดีกว่าเรียกวิธีหนึ่งมากกว่าคนแยกเป็นสัดส่วนถึงแม้คุณจะไม่ทราบว่าสิ่งที่ทำเพียงแค่มองรหัส (ดังนั้นคุณจะต้องหันไปดูที่ชื่อพารามิเตอร์และเอกสารประกอบเพื่อค้นหา - ซึ่งโดยส่วนตัวแล้วฉันจะทำทุกอย่างไม่ว่าฉันจะไม่คุ้นเคยกับ API) ตัวอย่างเช่นฉันเปิดเผยหนึ่งวิธีSetVisibility(bool, string, bool)ในFalconPeerและฉันรับทราบเพียงแค่ดูที่บรรทัด: …

8
“ Public APIs อยู่ตลอดกาล: โอกาสเดียวเท่านั้นที่จะทำให้ถูกต้อง”?
ในหนังสือ OS ฉันเพิ่งอ่านว่า "Public APIs อยู่ตลอดกาล: โอกาสเดียวเท่านั้นที่จะทำให้ถูกต้อง" จริงป้ะ? มันใช้ได้เฉพาะใน API ของระบบปฏิบัติการหรือ API อื่น ๆ ด้วยหรือไม่ ตัวอย่างเช่นสิ่งนี้จะเป็นจริงสำหรับ API ของแอปพลิเคชัน Android เช่น Tasker, Locale และ Pushover หรือไม่

4
ทำไม API การรวบรวม Java จึงไม่มีวิธีสุดท้าย [ปิด]
ปิด คำถามนี้เป็นคำถามความคิดเห็นตาม ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบข้อเท็จจริงและการอ้างอิงได้โดยแก้ไขโพสต์นี้ ปิดให้บริการใน5 ปีที่ผ่านมา นี่สำหรับคอลเลกชันที่ได้รับคำสั่งเช่น java.util.List ทำไมนักออกแบบภาษาจึงไม่มีวิธีสุดท้าย เหตุผลเดียวที่ฉันนึกได้คือ: ความกำกวมเมื่อการรวบรวมว่างเปล่า (ส่งคืนโมฆะหรือโยนข้อยกเว้น) API bloat มีเหตุผลอื่นอีกไหม?
19 java  api-design 

2
การออกแบบ REST API: การโทรหลายครั้งกับการโทรครั้งเดียวไปยัง API
เรากำลังพัฒนา Rest API สำหรับเว็บไซต์อีคอมเมิร์ซซึ่งแอพมือถือจะถูกใช้งาน ในหน้าแรกของแอพเราจำเป็นต้องโทรหาแหล่งข้อมูลมากมายเช่นสไลเดอร์แบรนด์ยอดนิยมสินค้าขายดี สองตัวเลือกในการโทรด้วย API: โทรเดียว: www.example.com/api/GetAllInHome โทรหลายสาย: www.example.com/api/GetSliders www.example.com/api/GetTopBrands www.example.com/api/GetBestSellingProducts www.example.com/api/GetTrendingProducts ซึ่งเป็นวิธีที่ดีที่สุดสำหรับการออกแบบ api พักผ่อน - โทรเดียวหรือหลายอธิบายข้อดีและข้อเสีย? ซึ่งจะใช้เวลามากขึ้นในการตอบสนองต่อการร้องขอ?
19 rest  api  api-design  url 

4
ฐานข้อมูลนามธรรม - มันมากเกินไปหรือไม่
หลังจากได้สัมผัสกับเลเยอร์สิ่งที่เป็นนามธรรมหลายชั้นฉันเริ่มสงสัยว่าประเด็นใดที่ห้องสมุดทุกแห่งคิดค้นกระบวนทัศน์ที่แตกต่างกันของพวกเขาเองในการเข้าถึงข้อมูล การรับ DAL ใหม่รู้สึกเหมือนได้เรียนรู้ภาษาใหม่อีกครั้งเมื่อสิ่งที่ฉันต้องการทำคือการโน้มน้าวให้เลเยอร์ส่งออกแบบสอบถาม SQL ที่ฉันได้เขียนไปแล้วในหัวของฉัน และนั่นคือโดยไม่ต้องสัมผัสกับการอ่านหลังจากข้อเท็จจริง: # Exhibit A: A typical DAL rows = db(db.ips_x_users.ip_addr == '127.0.0.1') .inner_join(db.ips_x_users.user_id == db.users.id) .select(order=(db.ips_x_users.last_seen, 'desc'), limit=10) # Exhibit B: Another typical DAL rows = db.ips_x_users .join(db.users, on=db.ips_x_users.user_id == db.users.id) .filter(db.ips_x_users.ip_addr == '127.0.0.1') .select(sort=~db.ips_x_users, limit=10) # Exhibit C: A hypothetical DAL based on …
18 database  sql  api-design  dsl 

4
ทำไม Java String จึงไม่มีวิธีการจัดการสตริงแบบคงที่
ทำไมนักออกแบบ Javaไม่สร้างวิธีการจัดการสตริงแบบคงที่ในjava.lang.Stringคลาส? วิธีการต่อไปนี้เป็นสิ่งที่ฉันอ้างถึง แต่คำถามสามารถขยายไปยังวิธีการไม่คงที่อื่น ๆ ในชั้นเรียนเช่นกัน concat(String) substring(int, int) replace(char, char) toLowerCase() replace(CharSequence, CharSequence) toLowerCase(Locale) replaceAll(String, String) toString() replaceFirst(String, String) toUpperCase() split(String) toUpperCase(Locale) split(String, int) trim() substring(int) การมีวิธีการเหล่านี้ในเวอร์ชันที่ไม่คงที่เท่านั้นจะบังคับให้มีการตรวจสอบ Null อย่างชัดเจนไม่ว่าที่ใดก็ต้องเรียกใช้ ยกตัวอย่างเช่นเพียงแค่โทรexample = example.trim()จะนำไปสู่NullPointerExceptionString example = nullถ้า ดังนั้นโปรแกรมเมอร์จะต้องทำการตรวจสอบ boilerplate null ต่อไปนี้: if (example != null) example = example.trim(); // OR: example …
17 java  api-design  null 

3
การตรวจจับ IEnumerable“ สถานะเครื่อง”
ฉันเพิ่งอ่านบทความที่น่าสนใจที่เรียกว่าน่ารักเกินไปกับผลตอบแทน c # มันทำให้ฉันสงสัยว่าวิธีที่ดีที่สุดคือการตรวจสอบว่า IEnumerable เป็นคอลเล็กชันที่นับได้จริงหรือว่าเป็นเครื่องสถานะที่สร้างด้วยคีย์เวิร์ด yield ตัวอย่างเช่นคุณสามารถแก้ไข DoubleXValue (จากบทความ) เป็นดังนี้: private void DoubleXValue(IEnumerable<Point> points) { if(points is List<Point>) foreach (var point in points) point.X *= 2; else throw YouCantDoThatException(); } คำถามที่ 1) มีวิธีที่ดีกว่าในการทำเช่นนี้หรือไม่? คำถามที่ 2) นี่คือสิ่งที่ฉันควรกังวลเมื่อสร้าง API หรือไม่
17 c#  api-design 

3
เมื่อใดที่ฉันควรใช้ string_view ในอินเทอร์เฟซ
ฉันใช้ห้องสมุดภายในที่ถูกออกแบบมาเพื่อเลียนแบบเสนอห้องสมุด C ++และในช่วงไม่กี่ปีที่ผ่านมาผมเห็นอินเตอร์เฟซที่เปลี่ยนจากการใช้เพื่อstd::stringstring_view ดังนั้นฉันจึงเปลี่ยนรหัสตามหน้าที่ให้สอดคล้องกับอินเทอร์เฟซใหม่ น่าเสียดายที่สิ่งที่ฉันต้องผ่านคือพารามิเตอร์ std :: string และสิ่งที่เป็นค่าส่งคืน std :: string ดังนั้นรหัสของฉันเปลี่ยนจากสิ่งนี้: void one_time_setup(const std::string & p1, int p2) { api_class api; api.setup (p1, special_number_to_string(p2)); } ถึง void one_time_setup(const std::string & p1, int p2) { api_class api; const std::string p2_storage(special_number_to_string(p2)); api.setup (string_view(&p1[0], p1.size()), string_view(&p2_storage[0], p2_storage.size())); } ฉันจริงๆไม่เห็นสิ่งที่เปลี่ยนแปลงนี้ซื้อฉันเป็นลูกค้าของ API นอกเหนือจากรหัสอื่น …

2
ควรใช้ทรัพยากรที่ซ้อนอยู่ใน RESTful API เมื่อใด
ฉันมีสองแหล่งข้อมูล: ผู้ใช้และลิงก์ ผู้ใช้สามารถมีหลายลิงค์ที่เกี่ยวข้อง ฉันได้ออกแบบ RESTful API ของฉันเพื่อให้คุณสามารถเข้าถึงลิงก์ที่เกี่ยวข้องกับผู้ใช้ได้ที่ URI ต่อไปนี้: /users/:id/links อย่างไรก็ตามฉันจำเป็นต้องมี URI เสมอสำหรับลิงก์ - บางครั้งฉันอาจต้องการลิงก์ทั้งหมดโดยไม่คำนึงถึงผู้ใช้ สำหรับสิ่งนี้ฉันมี: /links เสียงนี้ใช้ได้ไหม? มี URI สองตัวสำหรับลิงก์หรือไม่ ฉันสงสัยว่าฉันควรเข้าถึงลิงก์สำหรับผู้ใช้ที่มี URI หรือไม่เช่น: /links/user/:id หรือ /links/?user=:id ด้วยวิธีนี้ฉันมีแหล่งข้อมูลเพียงแหล่งเดียวสำหรับลิงก์
16 api  rest  api-design 

3
REST APIs การกำหนดเวอร์ชัน แต่ละ API มีเวอร์ชันของตัวเอง
เป็นเรื่องธรรมดามากที่จะระบุเวอร์ชันของ REST API ใน URL โดยเฉพาะที่จุดเริ่มต้นของเส้นทางนั่นคือ: POST /api/v1/accounts GET /api/v1/accounts/details อย่างไรก็ตามฉันไม่เห็นการออกแบบที่เกี่ยวข้องกับแต่ละ API กล่าวอีกนัยหนึ่งเรารักษาเวอร์ชันของแต่ละ API แยกจากกัน เช่น: POST /api/accounts/v2 GET /api/accounts/details/v3 การใช้วิธีการนี้ทำให้เราเพิ่มรุ่น API ของ API ที่เฉพาะเจาะจงเมื่อจำเป็นต้องทำการแตกหักการเปลี่ยนแปลงไม่จำเป็นต้องเพิ่มรุ่น API ทั้งหมด อะไรคือข้อเสียของการใช้สไตล์นี้แทนสไตล์ทั่วไป?

1
RESTful API และ i18n: จะออกแบบการตอบสนองอย่างไร?
เรากำลังออกแบบ RESTful API ที่มีวัตถุประสงค์เพื่อตอบสนองความต้องการของลูกค้าเป็นหลัก เนื่องจากสถานการณ์ที่เฉพาะเจาะจงลูกค้าจึงต้องทำการร้องขอให้น้อยที่สุดเท่าที่จะทำได้ API จัดการ i18n ผ่านส่วนหัว Accept-Language ในคำขอ สิ่งนี้ใช้ได้กับทุกสิ่งที่ลูกค้าต้องทำยกเว้นคุณลักษณะหนึ่งซึ่งลูกค้าต้องเก็บการตอบสนองของคำขอไปยังจุดปลายเดียวในสถานที่ที่มีอยู่ทั้งหมด เราสามารถออกแบบ API ในลักษณะที่ช่วยให้ลูกค้าสามารถดึงข้อมูลทั้งหมดนี้ได้ด้วยการร้องขอเพียงครั้งเดียวและไม่ทำลายการออกแบบ RESTful API ที่มีโครงสร้างที่สอดคล้องและมีโครงสร้างที่ดี ตัวเลือกที่เราพิจารณาแล้ว: การอนุญาตให้รวมหลายโลแคลในส่วนหัว Accept-Language และเพิ่มเวอร์ชันที่โลคัลไลซ์สำหรับโลแคลที่ร้องขอทั้งหมดในการตอบกลับแต่ละอันระบุด้วยรหัสภาษา ISO 639-1 เป็นคีย์ การสร้างบางสิ่งเช่นพารามิเตอร์ "? all_languages ​​= true" ไปยังปลายทางนั้นและส่งคืนเวอร์ชันที่แปลแล้วสำหรับโลแคลที่มีอยู่ทั้งหมดในการตอบกลับหากมีพารามิเตอร์นั้น (หากไม่มีสิ่งใดที่ได้ผลข้างต้นสำหรับเรา) ทำการร้องขอหลายครั้งเพื่อคว้าเวอร์ชั่นที่แปลเป็นภาษาท้องถิ่นทั้งหมดจากลูกค้า อันไหนเป็นทางเลือกที่ดีที่สุด?
15 rest  api  api-design  http 

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