feat: backendFetch에 PUT과 form-urlencoded 전송 추가
백엔드의 일부 변경 API는 @RequestBody 없이 VO를 받아 JSON 본문을 바인딩하지 못한다(관리자 등록·수정). 그런 엔드포인트를 부를 수 있게 form 옵션을 연다. Co-Authored-By: Claude Opus 5
@17f4b6ee823b13871dd162adce63f18bbed87f43
--- lib/http/backend-fetch.ts
+++ lib/http/backend-fetch.ts
... | ... | @@ -50,8 +50,14 @@ |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 | 52 |
type BackendRequestInit = {
|
| 53 |
- method: 'GET' | 'POST'; |
|
| 53 |
+ method: 'GET' | 'POST' | 'PUT'; |
|
| 54 | 54 |
body?: unknown; |
| 55 |
+ /** |
|
| 56 |
+ * form-urlencoded 본문. 백엔드의 일부 변경 API는 `@RequestBody` 없이 VO를 받아 JSON 본문을 |
|
| 57 |
+ * 바인딩하지 못한다(예: 관리자 등록·수정 — `@ParameterObject MngrAdminRequestVo`). 그런 |
|
| 58 |
+ * 엔드포인트는 이 필드를 쓴다. `body`와 함께 지정하지 않는다. |
|
| 59 |
+ */ |
|
| 60 |
+ form?: Record<string, string>; |
|
| 55 | 61 |
/** 쿼리 스트링 파라미터. 값은 문자열로 직렬화해 붙인다. */ |
| 56 | 62 |
query?: Record<string, string | number>; |
| 57 | 63 |
/** |
... | ... | @@ -182,12 +188,18 @@ |
| 182 | 188 |
response = await fetch(resolveUrl(path, init.query), {
|
| 183 | 189 |
method: init.method, |
| 184 | 190 |
headers: {
|
| 185 |
- 'Content-Type': 'application/json', |
|
| 191 |
+ 'Content-Type': init.form |
|
| 192 |
+ ? 'application/x-www-form-urlencoded' |
|
| 193 |
+ : 'application/json', |
|
| 186 | 194 |
...(init.accessToken |
| 187 | 195 |
? { Authorization: `Bearer ${init.accessToken}` }
|
| 188 | 196 |
: {}),
|
| 189 | 197 |
}, |
| 190 |
- body: init.body !== undefined ? JSON.stringify(init.body) : undefined, |
|
| 198 |
+ body: init.form |
|
| 199 |
+ ? new URLSearchParams(init.form).toString() |
|
| 200 |
+ : init.body !== undefined |
|
| 201 |
+ ? JSON.stringify(init.body) |
|
| 202 |
+ : undefined, |
|
| 191 | 203 |
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), |
| 192 | 204 |
cache: init.cache, |
| 193 | 205 |
next: init.next, |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?