【问题标题】:FastAPI conflict path parameter in endpoint - good practices?端点中的 FastAPI 冲突路径参数 - 良好做法?
【发布时间】:2021-09-28 03:36:17
【问题描述】:

我正在使用 FastAPI 为资源 student 创建 2 个 GET 方法。我希望通过两种方式获得student:student_id 或student_name。

问题是,我最初创建的 2 个端点如下

@app.get("/student/{student_name}", response_model=schemas.Student, status_code=200)
def get_student_by_name(student_name: str, db: Session = Depends(get_db)):
    db_student = crud.get_student_by_name(db, student_name)
    if db_student is None:
        raise HTTPException(status_code=404, detail="Student not found")
    return db_student


@app.get("/student/{student_id}", response_model=schemas.Student, status_code=200)
def get_student_by_id(student_id: int, db: Session = Depends(get_db)):
    db_student = crud.get_student_by_id(db, student_id)
    if db_student is None:
        raise HTTPException(status_code=404, detail="Student not found")
    return db_student

问题是端点名称相互冲突,它都是/student 后跟一个参数并且只有一个可以工作 - 在这种情况下只有/student/{student_name} 因为它是在前面定义的。所以我想出了这个简单的解决方法,在端点名称中添加更多内容:

@app.get("/student/{student_name}", response_model=schemas.Student, status_code=200)
def get_student_by_name(student_name: str, db: Session = Depends(get_db)):
    db_student = crud.get_student_by_name(db, student_name)
    if db_student is None:
        raise HTTPException(status_code=404, detail="Student not found")
    return db_student


@app.get("/student/byid/{student_id}", response_model=schemas.Student, status_code=200)
def get_student_by_id(student_id: int, db: Session = Depends(get_db)):
    db_student = crud.get_student_by_id(db, student_id)
    if db_student is None:
        raise HTTPException(status_code=404, detail="Student not found")
    return db_student

我在get_student)by_id 方法的端点名称中添加了/byid。虽然两个端点现在都可以工作,但我想知道这是否被认为是一种好的做法?当需要使用单个路径参数查询一个资源以区分端点名称时,最佳做法是什么?

【问题讨论】:

标签: python rest backend fastapi endpoint


【解决方案1】:

我会做这样的事情

@app.get("/student/{student_id}", response_model=schemas.Student, status_code=200)
def get_student(student_id: str, db: Session = Depends(get_db)):
    db_student = crud.get_student_by_id(db, student_id)
    if db_student is None:
        raise HTTPException(status_code=404, detail="Student not found")
    return db_student


# use search criterias as query params
@app.get("/student/", response_model=List[schemas.Student], status_code=200)
def get_students(student_name: string = None, db: Session = Depends(get_db)):
    # Query inside your crud file
    query = db.query(Student)
    if student_name:
        # if you want to search similar items
        query = query.filter(Student.name.like(f"%{student_name}%"))
        # if you want to search an exact match
        query = query.filter(Student.name == student_name)
    
    return query.all()

有了这个,你的代码将对未来的变化更加开放,我只会在按 id 搜索时使用 url 参数,任何其他搜索条件都可以使用查询参数作为过滤参数处理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    • 2020-11-03
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2021-02-15
    相关资源
    最近更新 更多