端点中的 FastAPI 冲突路径参数 - 好的做法?
FastAPI conflict path parameter in endpoint - good practices?
我正在使用 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
。虽然现在两个端点都可以工作,但我想知道这是否被认为是一种好的做法?当需要使用单个路径参数查询一个资源以区分端点名称时,最佳做法是什么?
我会做这样的事情
@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 参数,任何其他搜索条件都可以使用查询参数作为过滤器参数处理
我正在使用 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
。虽然现在两个端点都可以工作,但我想知道这是否被认为是一种好的做法?当需要使用单个路径参数查询一个资源以区分端点名称时,最佳做法是什么?
我会做这样的事情
@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 参数,任何其他搜索条件都可以使用查询参数作为过滤器参数处理