ถือว่าเป็นการใช้งาน HTTP POST โดยไม่ต้องมีเอนทิตีหรือไม่


176

ฉันต้องเรียกใช้กระบวนการที่ไม่ต้องการข้อมูลใด ๆ จากผู้ใช้เพียงเป็นตัวกระตุ้น ฉันวางแผนที่จะใช้ POST / uri โดยไม่มีร่างกายเพื่อกระตุ้นกระบวนการ ฉันต้องการทราบว่าสิ่งนี้ถือว่าไม่ดีทั้งในมุมมอง HTTP และ REST หรือไม่


6
ขอบคุณทุกคนสำหรับคำแนะนำของคุณ แม้ว่าทุกคนจะให้คำแนะนำที่คล้ายกันนั่นก็โอเคที่จะโพสต์โดยไม่มีเนื้อหา แต่ฉันเลือกคำตอบของ Darrel ว่าถูกต้องเนื่องจากลิงก์ไปยังการอภิปรายของ IETF การอภิปรายชี้แจงมาก
Suresh Kumar

คำตอบ:


155

ฉันถามคำถามนี้ในคณะทำงาน IETF HTTP เมื่อไม่กี่เดือนที่ผ่านมา คำตอบสั้น ๆ คือ: ไม่ใช่ไม่ใช่การปฏิบัติที่ไม่ดี (แต่ฉันขอแนะนำให้อ่านรายละเอียดเพิ่มเติม)


4
มีแหล่งข้อมูลอัปเดตใดบ้างที่จะยืนยันว่า 10 ปีต่อมา
Baptiste Pernet

79

การใช้ POST แทน GET นั้นสมเหตุสมผลอย่างสมบูรณ์เพราะมันยังสั่งให้เซิร์ฟเวอร์ (และเกตเวย์ไปพร้อมกัน) ไม่ให้ส่งคืนการตอบกลับที่แคชไว้


50

โพสต์ตกลงอย่างสมบูรณ์ ในความแตกต่างของ GET กับ POST คุณกำลังเปลี่ยนสถานะของระบบ (เป็นไปได้มากว่าทริกเกอร์ของคุณคือ "กำลังทำอะไร" และเปลี่ยนแปลงข้อมูล)

ฉันใช้ POST แล้วโดยไม่มีส่วนของข้อมูลและ "รู้สึก" ตกลง สิ่งหนึ่งที่คุณควรจะทำอย่างไรเมื่อใช้ POST โดยไม่ต้องน้ำหนักบรรทุก: Content-Length: 0หัวผ่าน ฉันจำปัญหาเกี่ยวกับพร็อกซี่บางอย่างเมื่อฉันลูกค้า API ไม่ผ่านมัน


16

หากคุณใช้ POST / uri ที่ไม่มีเนื้อความมันก็เหมือนกับการใช้ฟังก์ชั่นที่ไม่รับอาร์กิวเมนต์ .eg int post (void); ดังนั้นจึงมีเหตุผลที่จะมีฟังก์ชั่นคลาสทรัพยากรของคุณซึ่งสามารถเปลี่ยนสถานะของวัตถุโดยไม่ต้องมีข้อโต้แย้ง หากคุณพิจารณาที่จะใช้ฟังก์ชั่น Unix touch สำหรับ URI มันจะเป็นตัวเลือกที่ดีหรือไม่?


6
Touch / finger เป็นภาพประกอบของการกระทำที่ไม่ใช้ idempotent ซึ่งเป็นเนื้อหาที่ไม่มีเนื้อหา
Chris Marisic

2

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

ตัวอย่างเช่นหากคุณต้องการโพสต์ 'hello world' ถึงและจุดสิ้นสุดคุณจะต้องทำให้มันเป็นดังนี้: http://api.com?param=hello%20world


0

การสนับสนุนคำตอบที่ POST ใช้ได้ในกรณีนี้ก็คือในกรณีของ Pythons กรอบงาน OpenAPI "FastAPI" จะสร้าง Swagger GUI (ดูภาพ) ที่ไม่มีส่วนเนื้อความเมื่อวิธี (ดูตัวอย่างด้านล่าง) ไม่ได้ มีพารามิเตอร์ที่จะยอมรับร่างกาย

เมธอด "post_disable_db" เพียงยอมรับพารามิเตอร์พา ธ "db_name" และไม่มีพารามิเตอร์ที่ 2 ซึ่งจะบ่งบอกถึงเนื้อความบังคับ

@router.post('/{db_name}/disable',
             status_code=HTTP_200_OK,
             response_model=ResponseSuccess,
             summary='',
             description=''
             )
async def post_disable_db(db_name: str):
    try:
        response: ResponseSuccess = Handlers.databases_handler.post_change_db_enabled_state(db_name, False)
    except HTTPException as e:
        raise (e)
    except Exception as e:
        logger.exception(f'Changing state of DB to enabled=False failed due to: {e.__repr__()}')
        raise HTTPException(HTTP_500_INTERNAL_SERVER_ERROR, detail=e.__repr__())

    return response

ป้อนคำอธิบายรูปภาพที่นี่

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