FastApiのよく使うリクエスト方法　例３選

# ①パスパラメータ
/categories/1
id=1となる

```
@router.get("/{id}", response_model=schemas.Category)
async def read_category_by_id(
    *,
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_active_user),
    id: int,
) -> Any:
```
 
JSで送る時
```
instance.get(`/categories/${id}`, authHeaders(token));
```

# ②スキーマ（Schemas） - リクエスト
Content-Type: application/json
構造で送る（受け取る）

```
@router.post("/", response_model=schemas.Category)
async def create_category(
    *,
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_active_user),
    category_in: schemas.CategoryCreate,
) -> Any:
```

JSで送る時
```
data = {
  CategoryCreate.key1: val1,
  CategoryCreate.key2: val2,
}

instance.post("/categories/", data, authHeaders(token));
```

# ③マルチパート
 
'Content-Type': 'multipart/form-data'
 
これが特殊
 
構造で送る（受け取る）　
　＋
Fileを同時に送る
 
（メール送信の本文と添付ファイルのイメージ）

```
@router.post("/edit/{quotation_id}", response_model=schemas.Quotation)
async def edit_quotation(
    *,
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_active_user),
    quotation_id: int,
    quotation_in: schemas.QuotationEdit = Body(...),
    files: List[UploadFile] = File([]),
) -> Any:
```

ここの分がマルチパートになります
quotation_in: schemas.QuotationEdit = Body(...),
    files: List[UploadFile] = File([]),

QuotationEdit

 quotation_in=jsonStringなので、変換してやる
 
```
class QuotationEdit(QuotationEditBase):

    @model_validator(mode="before")
    @classmethod
    def validate_to_json(cls, value):
        if isinstance(value, str):
            return cls(**json.loads(value))
        return value
```


JSで送る時
``` 
    async editQuotation(token, id, data, files) {
        const form = new FormData();
        // let value;
        form.append('quotation_in', JSON.stringify(data));
        //複数送りたいときは配列にしてあげる
        files.forEach(file => {
            form.append('files', file.file, file.name || file.file.name || file.file.filename)
        });
        let config = authHeaders(token, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        });
        return instance.post(`/quotations/edit/${id}`, form, config);
    },
```

pytest

```
def test_edit_quotation(client, setup_db_for_test_fixture1):
    # Preparing multipart/form-data
    quotation_in = {
        "id": 1,
        "quotation_title": "string",
        "quo_tree_data": {},
        "cost_tree_data": {},
        "tax_excluded_suggested_price": 0,
        "remarks": {},
        "quo_remarks": "string",
        "tax_id": 1,
        "discount_price": 0,
        "attached_files": {},
        "withinoffice_memo": "string",
        "notices": "string",
        "accept_conditions": "string",
        "comments": "string",
        "risk_fee_id": 1,
        "deadline_date": "2024-09-09",
        "quo_user_id": 1,
        "cost_user_id": 1,
        "quo_approver_id": 1,
        "cost_approver_id": 1,
        "updated_user_id": 1,
    }
    form_data = {"quotation_in": json.dumps(quotation_in)}
    files = [
        ("files", open("tests/endpoints/quotations/__init__.py", "rb")),
        ("files", open("tests/endpoints/quotations/conftest.py", "rb")),
    ]
    # multipart
    client = TestClient(
        app=app,
        base_url="http://testserver/api",
    )

    response = client.post(f"/{endpoints}/edit/1", data=form_data, files=files)

    assert response.status_code == 200
```