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

application programming interface (API) เป็นข้อกำหนดสำหรับซอฟต์แวร์อื่นที่ใช้กับซอฟต์แวร์อื่น

10
การออกแบบ API: แนวทางที่เป็นรูปธรรมและเป็นนามธรรม - แนวทางปฏิบัติที่ดีที่สุด
เมื่อพูดคุยเกี่ยวกับ API ระหว่างระบบ (ในระดับธุรกิจ) มักจะมีมุมมองที่แตกต่างกันสองประการในทีมของเรา: บางคนชอบมากกว่า - ให้พูดว่า - วิธีนามธรรมทั่วไป ตัวอย่าง: การออกแบบ API ค้นหา "บุคคล" แบบง่าย รุ่นที่เป็นรูปธรรมจะเป็น searchPerson(String name, boolean soundEx, String firstName, boolean soundEx, String dateOfBirth) คนที่ชื่นชอบเวอร์ชั่นคอนกรีตพูดว่า: API คือการจัดทำเอกสารด้วยตนเอง มันง่ายที่จะเข้าใจ มันง่ายต่อการตรวจสอบ (คอมไพเลอร์หรือเป็นเว็บเซอร์: การตรวจสอบสคีมา) จูบ กลุ่มคนอื่น ๆ ในทีมของเราจะพูดว่า "นั่นเป็นเพียงรายการของเกณฑ์การค้นหา" searchPerson(List<SearchCriteria> criteria) กับ SearchCritera { String parameter, String value, Map<String, String> …

2
การเปิดเผยรหัส C ++ ต่อสาธารณะเป็น C API หมายความว่าอย่างไรและข้อดีของการทำคืออะไร
ฉันมักจะได้ยินคนพูดว่าโปรแกรมเมอร์ C ++ ควรเปิดเผย API สาธารณะของห้องสมุด / ผลิตภัณฑ์เป็น C API นั่นหมายถึงอะไรและข้อดีของมันคืออะไร?
25 c++  c  api 

6
ฉันควรใส่คำขอ API ไว้ที่ MVC ที่ไหน
ฉันกำลังสร้างเว็บแอปพลิเคชันโดยใช้รูปแบบ MVC ต่อไปนี้ชนิดของสถาปัตยกรรมนี้เราจะเห็นว่าวิธีการทั้งหมดที่ใช้ในการติดต่อกับฐานข้อมูลจะดำเนินการในรูปแบบ แต่จะเกิดอะไรขึ้นถ้าฉันต้องเรียกบริการที่ผู้อื่นเปิดเผยบนเว็บ ตัวอย่างเช่นฉันต้องการเข้าถึง Facebook API เพื่อรับผู้ติดตามทั้งหมดในหน้าของฉันดังนั้นฉันจะวางวิธีการเหล่านี้ไว้ที่ไหน เห็นได้ชัดว่ามุมมองที่ไม่เป็นความคิดที่ดีเพราะโมดูลนี้จะทุ่มเทให้กับงานนำเสนอที่ควบคุมไม่ควรนำมาใช้ในการดึงข้อมูล แต่รุ่นมักจะมีความมุ่งมั่นเท่านั้นที่จะมีปฏิสัมพันธ์กับฐานข้อมูล ดังนั้นคุณสามารถให้คำแนะนำฉันเกี่ยวกับสิ่งนั้นได้ไหม และโปรดคุณช่วยบอกฉันได้ไหมว่าฉันทำผิดพลาดเกี่ยวกับสถาปัตยกรรม MVC หรือไม่
25 mvc  api 

6
สิ่งที่จะเรียก HTTP API ที่ไม่สงบ [ปิด]
ปิด คำถามนี้เป็นคำถามความคิดเห็นตาม ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบข้อเท็จจริงและการอ้างอิงได้โดยแก้ไขโพสต์นี้ ปิดให้บริการ4 ปีที่แล้ว คุณจะเรียก API ที่ใช้ HTTP ใช้ URI เพื่อตั้งชื่อทรัพยากรและกริยา HTTP (PUT, POST, DELETE, GET ... ) เพื่อจัดการทรัพยากรเหล่านั้นอย่างไร ตามการร้องเรียนของ Roy Fieldingไม่ใช่การพักเนื่องจากไม่มีไฮเปอร์มีเดีย ภายในทีมของฉันทุกคนเรียกมันว่า "REST API" ฉันเรียกมันว่า "REST-like" แต่มันไม่ได้อธิบายและความหมายของมันนั้นคลุมเครือ ฉันค่อนข้างสับสนเกี่ยวกับเรื่องนี้เนื่องจากมีความขัดแย้งอย่างมากเกี่ยวกับ REST ฉันไม่ต้องการมีส่วนร่วมในสงครามไฟ แต่เพียงใช้คำที่ถูกต้อง
24 terminology  rest  api  http 

4
ต้องการตัวอย่างมากกว่าเอกสาร มันเป็นปัญหาพฤติกรรมหรือไม่?
เมื่อใดก็ตามที่ฉันเจอAPIใหม่หรือภาษาการเขียนโปรแกรมหรือแม้แต่หน้าลินุกซ์อย่างง่ายฉันมักจะหลีกเลี่ยงพวกเขา (นับตั้งแต่ที่ฉันจำได้) และมักจะพึ่งพาตัวอย่างเพื่อทำความเข้าใจแนวคิดใหม่ ๆ โดยไม่รู้ตัวฉันจะหลีกเลี่ยงเอกสาร / API ทุกครั้งที่มันไม่ตรงไปตรงมาหรือเป็นความลับหรือน่าเบื่อเพียงธรรมดา เป็นเวลาหลายปีแล้วที่ฉันเริ่มเขียนโปรแกรมและตอนนี้ฉันรู้สึกว่าฉันต้องแก้ไขวิธีการของฉันเมื่อฉันรู้ว่าฉันสร้างความเสียหายมากขึ้นโดยการละเว้นจากการอ่านเอกสารที่เป็นความลับ / ยากเนื่องจากยังดีกว่าตัวอย่างเป็นทางการ เอกสารมีความครอบคลุมมากกว่าตัวอย่างจากที่นั่น แม้หลังจากตระหนักว่าตัวอย่างควรได้รับการปฏิบัติเหมือนเป็นค่า "เพิ่ม" แทนที่จะเป็นแหล่ง "หลัก" สำหรับการเรียนรู้ ฉันจะทำลายนิสัยที่ไม่ดีนี้ในฐานะโปรแกรมเมอร์หรือฉันคิดมากได้อย่างไร

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

6
เหตุใดจึงต้องใช้บริการ (REST / SOAP) แทนที่จะเป็นห้องสมุด
สมมติว่าคุณกำลังมองหาการแยกแอปพลิเคชันของคุณลงในบริการ มีเหตุผลที่ดีบ้างไหมในการนำแนวทาง SOA มาใช้กับการสร้างไลบรารี่ API ที่สามารถโหลดได้โดยแอพพลิเคชั่นที่ต้องการ
22 api  soa  services 

11
เป็นทักษะที่จำเป็นสำหรับโปรแกรมที่ไม่มีเอกสาร API หรือไม่? [ปิด]
ปิด คำถามนี้เป็นคำถามความคิดเห็นตาม ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบข้อเท็จจริงและการอ้างอิงได้โดยแก้ไขโพสต์นี้ ปิดให้บริการใน4 ปีที่แล้ว ฉันเพิ่งผ่านการสอบการเขียนโปรแกรมจาวาวันนี้ ฉันต้องตอบคำถามทั่วไปเกี่ยวกับการทำเกลียวซึ่งทำได้ดีและต้องเขียนโปรแกรมแบบเธรดเล็กน้อยซึ่งแย่กว่านั้น ฉันต้องเชื่อมต่อแล็ปท็อปของฉันกับหน้าจอโปรเจ็กเตอร์และเขียนโปรแกรมทันที ความพยายามครั้งแรกของฉันคือการใช้คลาสที่ไม่ระบุชื่อ แต่ฉันลืมไวยากรณ์ที่แน่นอน อาจจะเป็นเพราะความตื่นเต้นหรืออาจเป็นเพราะสองสัปดาห์ที่แล้วฉันเขียนโปรแกรมเป็นส่วนใหญ่ใน php จากนั้นฉันก็ถามว่าจะอนุญาตให้ใช้เอกสาร API หรือไม่ คำตอบคือ "ไม่" ดังนั้นฉันตัดสินใจที่จะไปอีกทางหนึ่งและฉันก็ใช้ Runnable โปรแกรมกำลังทำสิ่งที่ร้องขอในตอนท้าย แน่นอนว่าผู้ตรวจสอบสังเกตเห็นความล้มเหลวครั้งแรกของฉันและนั่นส่งผลต่อคะแนนของฉันอย่างมาก ฉันประหลาดใจที่ไม่อนุญาตให้ใช้เอกสาร API ดังนั้นคำถามของฉันคือ: มันสำคัญหรือไม่ที่จะสามารถเขียนโค้ดได้อย่างไม่มีที่ติหากไม่มีเอกสาร API ฉันควรพัฒนาทักษะนี้หรือไม่? มันสำคัญจริง ๆ ในโลกจริงและในสภาพแวดล้อมการทำงานหรือไม่ ในขณะที่หลักสูตรการเขียนโปรแกรมฉันเน้นรูปแบบการเรียนรู้การพัฒนาทักษะการเขียนแอปพลิเคชันการออกแบบที่ดีทักษะการใช้ API และค้นหาข้อมูลที่จำเป็นได้อย่างรวดเร็ว ฉันไม่ได้พยายามเรียนรู้วิธีการเขียนโปรแกรมโดยไม่มีเอกสาร API มันจะต้องมีในระหว่างการสัมภาษณ์งาน (การเข้ารหัสโดยไม่มีเอกสารประกอบ API)?

3
เป็นการออกแบบปกติหรือไม่ที่จะแยกแบ็กเอนด์และส่วนหน้าเว็บแอปพลิเคชันอย่างสมบูรณ์และอนุญาตให้พวกเขาสื่อสารกับ (JSON) REST API ได้หรือไม่?
ฉันกำลังสร้างเว็บแอปพลิเคชันธุรกิจใหม่และฉันต้องการบรรลุ: ใช้เทคโนโลยีที่ดีที่สุดจากอาณาจักรที่เกี่ยวข้อง ฉันต้องการกรอบแบ็กเอนด์ที่เชื่อถือได้ด้วย ORM ที่มั่นคง และฉันต้องการเฟรมเวิร์ก SPA (แอปพลิเคชันหน้าเดียว) ที่ทันสมัยที่สุดด้วยการใช้คุณสมบัติ HTML และ Javascript ล่าสุดสำหรับแอปพลิเคชันส่วนหน้า เปิดเผยเอนทิตีแบ็กเอนด์และบริการธุรกิจสำหรับการใช้งานจากแอพพลิเคชั่นประเภทต่าง ๆ เช่นเว็บแอพพลิเคชั่นมือถือ (Android) และประเภทอื่น ๆ (อุปกรณ์สมาร์ทเป็นต้น) ดังนั้น - เพื่อตอบสนองความต้องการทั้งสองอย่างฉันมีแนวโน้มที่จะแยกแอปพลิเคชันของฉันออกอย่างสมบูรณ์ในแอปพลิเคชันส่วนหลังและส่วนหน้าและจัดการการสื่อสารระหว่างกันโดยใช้ REST API (JSON) เสียงนี้เข้าใกล้หรือไม่? การแยกดังกล่าวไม่ใช่โซลูชันการออกแบบที่ชัดเจนเนื่องจากเทคโนโลยีเว็บแอปพลิเคชันจำนวนมากได้รวมเลเยอร์มุมมองไว้ซึ่งแอปพลิเคชันฝั่งเซิร์ฟเวอร์จะควบคุมการสร้างมุมมองมากขึ้นหรือน้อยลงและจัดการการตอบสนองจากมุมมองบางส่วน layer, Java JSF / Facelets จะบันทึกสถานะของส่วนประกอบบนเซิร์ฟเวอร์อย่างสมบูรณ์) ดังนั้น - มีเทคโนโลยีมากมายที่เสนอการมีเพศสัมพันธ์ที่แข็งแกร่งมากขึ้นและให้สัญญาว่าจะพัฒนาได้เร็วขึ้นและมีเส้นทางการเดินทางที่เป็นมาตรฐานมากขึ้น ดังนั้น - ฉันต้องระวังเมื่อเริ่มใช้เทคโนโลยีในลักษณะที่ไม่ได้ใช้กันอย่างแพร่หลาย ตามที่ฉันเข้าใจแล้วส่วนหน้าของ SPA ที่แยกจากกันอย่างสมบูรณ์มักเกิดจากความจำเป็นในการใช้ API ของบุคคลที่สาม แต่การออกแบบเสียง decoupling ดังกล่าวเมื่อทั้งสองแบ็กเอนด์และส่วนหน้าได้รับการพัฒนาโดย บริษัท หนึ่ง? …

7
ฉันจะจัดการชุดกฎและหมายเลขมายากลที่มีขนาดใหญ่มากในโปรแกรมของฉันได้อย่างไร
ฉันค่อนข้างใหม่ในการเขียนโปรแกรม (ฉันเป็นวิศวกรเครื่องกลโดยการค้า) และฉันกำลังพัฒนาโปรแกรมขนาดเล็กในช่วงเวลาหยุดทำงานของฉันที่สร้างชิ้นส่วน (solidworks) ตามการป้อนข้อมูลจากผู้คนต่าง ๆ จากโรงงาน จากอินพุตเพียงเล็กน้อย (6 ต่อแน่นอน) ฉันต้องทำการเรียก API หลายร้อยครั้งที่สามารถใช้พารามิเตอร์มากถึงสิบตัว ทั้งหมดสร้างขึ้นโดยชุดของกฎที่ฉันรวบรวมหลังจากสัมภาษณ์ทุกคนที่จัดการส่วนนั้น ส่วนกฎและพารามิเตอร์ของรหัสของฉันคือ 250 บรรทัดและเพิ่มขึ้น ดังนั้นวิธีที่ดีที่สุดในการรักษาและอ่านรหัสของฉันคืออะไร? ฉันจะแยกหมายเลขเวทย์มนตร์ทั้งหมดกฎทั้งหมดอัลกอริธึมและส่วนของขั้นตอนของรหัสได้อย่างไร ฉันจะจัดการกับ API ที่ละเอียดและละเอียดมากได้อย่างไร เป้าหมายหลักของฉันคือการสามารถมอบแหล่งข้อมูลให้ใครบางคนและให้พวกเขาเข้าใจในสิ่งที่ฉันทำ

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
'การค้นพบ' ใน REST API ต้องการอะไรเมื่อลูกค้ายังไม่ก้าวหน้าพอที่จะใช้มันได้
การพูดคุยที่หลากหลายที่ฉันได้ดูและแบบฝึกหัดที่ฉันสแกนบน REST ดูเหมือนจะเน้นสิ่งที่เรียกว่า 'การค้นพบ' สำหรับความเข้าใจที่ จำกัด ของฉันคำศัพท์น่าจะหมายถึงว่าลูกค้าควรจะสามารถไปhttp://URL- และรับรายการสิ่งที่สามารถทำได้โดยอัตโนมัติ สิ่งที่ฉันมีปัญหาในการทำความเข้าใจ - คือ 'ลูกค้าซอฟต์แวร์' ไม่ใช่มนุษย์ พวกเขาเป็นเพียงโปรแกรมที่ไม่มีความรู้ที่เข้าใจง่ายเพื่อทำความเข้าใจว่าจะทำอย่างไรกับลิงก์ที่ให้ไว้ มีเพียงคนเท่านั้นที่สามารถไปที่เว็บไซต์และทำความเข้าใจกับข้อความและลิงก์ที่นำเสนอและดำเนินการกับมัน ดังนั้นจุดของการค้นพบคืออะไรเมื่อรหัสลูกค้าที่เข้าถึง URL ที่ค้นพบดังกล่าวไม่สามารถทำอะไรกับมันได้เว้นแต่ผู้พัฒนามนุษย์ของลูกค้าจะทำการทดลองจริง ๆ กับทรัพยากรที่นำเสนอ? ดูเหมือนว่าสิ่งเดียวกันกับการกำหนดชุดของฟังก์ชั่นที่มีอยู่ในคู่มือเอกสารเพียงจากทิศทางที่แตกต่างและจริง ๆ แล้วเกี่ยวข้องกับการทำงานมากขึ้นสำหรับนักพัฒนา เหตุใดแนวทางที่สองนี้ของการกำหนดล่วงหน้าสิ่งที่สามารถทำได้ในเอกสารภายนอกกับทรัพยากร REST ที่แท้จริงถือว่าต่ำกว่า
20 rest  api  hateoas 

4
ควรใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางตรรกะทางธุรกิจบนเซิร์ฟเวอร์หรือไม่?
ฉันกำลังอยู่ระหว่างทางแยกที่มีการออกแบบ API บางอย่างสำหรับลูกค้า (JS ในเบราว์เซอร์) เพื่อพูดคุยกับเซิร์ฟเวอร์ เราใช้ HTTP 409 Conflict เพื่อแสดงถึงความล้มเหลวของการกระทำเนื่องจากมีการล็อคเพื่อความปลอดภัย ล็อค satefy ป้องกันไม่ให้ devs ทำการเปลี่ยนแปลงในระบบการผลิตของลูกค้าโดยไม่ได้ตั้งใจ ฉันได้รับมอบหมายให้จัดการ 409 บิตให้กับลูกค้าอย่างอ่อนโยนยิ่งขึ้นเพื่อระบุว่าเหตุใดการเรียก API เฉพาะจึงล้มเหลว โซลูชันของฉันคือการตัดตัวจัดการความล้มเหลวของการโทร AJAX ใด ๆ ของเราซึ่งจะแสดงการแจ้งเตือนลูกค้าเมื่อมีบางอย่างล้มเหลวเนื่องจาก 409 - ทั้งหมดนี้ใช้ได้และทำงานได้ดีพร้อมกับข้อผิดพลาด 4XX และ 5XX อื่น ๆ ที่ใช้กลไกเดียวกัน มีปัญหาเกิดขึ้นที่หนึ่งในตัวจัดการเส้นทางของเราตอบสนองกับ 409s เมื่อพบข้อผิดพลาดทางธุรกิจตรรกะ - AJAX wrapper ของฉันรายงานว่าล็อคความปลอดภัยอยู่ในขณะที่ลูกค้าจัดการความล้มเหลวที่มีอยู่รายงานสิ่งที่มันคิดว่ามันขึ้นอยู่กับร่างกาย ของการตอบสนอง วิธีแก้ปัญหาง่ายๆคือเปลี่ยนการตอบสนองของผู้จัดการหรือรหัสสถานะที่เราใช้เพื่อเป็นตัวแทนของล็อคความปลอดภัย ซึ่งนำฉันไปสู่ทางแยกของฉัน: ควรใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางตรรกะทางธุรกิจหรือไม่ คำถามนี้เน้นปัญหาเดียวกันกับที่ฉันเผชิญ แต่ก็ไม่ได้รับแรงฉุดมากนัก …
20 rest  api  web 

4
ทำไมไม่ใช้ SQL แทน GraphQL
เมื่อเร็ว ๆ นี้ฉันได้เรียนรู้เกี่ยวกับ GraphQL ซึ่งอ้างว่าเหนือกว่า RESTful อย่างไรก็ตามฉันเริ่มสงสัยว่าทำไมเราไม่ใส่คำสั่ง SQL ลงในคำขอ HTTP GET ตัวอย่างเช่นใน GraphQL ฉันจะเขียน { Movie(id: "cixos5gtq0ogi0126tvekxo27") { id title actors { name } } } ซึ่งไม่ง่ายกว่า SQL แบบเดียวกัน SELECT id, title FROM movies WHERE id = cixos5gtq0ogi0126tvekxo27; SELECT actors.name FROM actors, actors_movies WHERE actors.id == movies.actor_id AND movie.id == …

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