第3回/REST_API
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
[[第3回]]
* REST API [#k72e7252]
- テキストはパワーポイントを参照のこと
** ToDo管理アプリにWeb-APIを実装する [#vc9829bb]
*** やりたいこと [#de855ec6]
- ToDo管理のためのRESTfulなAPIを作成する
- POST/GET/PUT/DELTE をそれぞれ CRUDに対応させる
- フォームはJSONで送る
-- @ModelAttributeではなく,@RequestBody で受けること
*** API仕様 [#y966b67b]
|操作|API呼び出し|戻り値|h
|ToDo作成|POST /api/{uid}/todos {"title": "タイトル"}|作...
|ToDo取得|GET /api/{uid}/todos/{seq}|指定したToDoオブジェ...
|ToDo取得|GET /api/{uid}/todos |そのユーザのToDoリスト|
|ToDo取得|GET /api/{uid}/dones |そのユーザのDoneリスト|
|ToDo更新|PUT /api/{uid}/todos/{seq}/done|完了したToDoオ...
|ToDo更新|PUT /api/{uid}/todos/{seq} {"title":"変更するタ...
|ToDo削除|DELETE /api/{uid}/todos/{seq}|true|
*** RESTController - RESTコントローラ [#x3611e1a]
- controller/ToDoRestController
package jp.ac.kobe_u.cs.itspecialist.todoapp.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Auto...
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validat...
import org.springframework.web.bind.MethodArgumentNotVal...
import org.springframework.web.bind.annotation.DeleteMap...
import org.springframework.web.bind.annotation.Exception...
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVaria...
import org.springframework.web.bind.annotation.PostMappi...
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBo...
import org.springframework.web.bind.annotation.RequestMa...
import org.springframework.web.bind.annotation.RestContr...
import jp.ac.kobe_u.cs.itspecialist.todoapp.dto.ToDoForm;
import jp.ac.kobe_u.cs.itspecialist.todoapp.entity.ToDo;
import jp.ac.kobe_u.cs.itspecialist.todoapp.exception.To...
import jp.ac.kobe_u.cs.itspecialist.todoapp.service.Memb...
import jp.ac.kobe_u.cs.itspecialist.todoapp.service.ToDo...
/**
* ToDoの操作,CRUDを行うAPI
*/
@RestController
@RequestMapping("/api")
public class ToDoRestController {
@Autowired
ToDoService todoService;
@Autowired
MemberService memberService;
/* --- C: ToDoを作成する --- */
@PostMapping("/{mid}/todos")
ToDo createToDo(@PathVariable String mid, @Validated...
return todoService.createToDo(mid, form);
}
/* --- R: ToDoを取得する (1件) --- */
@GetMapping("/{mid}/todos/{seq}")
ToDo getToDoList(@PathVariable String mid, @PathVari...
return todoService.getToDo(seq);
}
/* --- R: ToDoを取得する (リスト) --- */
@GetMapping("/{mid}/todos")
List<ToDo> getToDoList(@PathVariable String mid) {
return todoService.getToDoList(mid);
}
/* --- R: Doneを取得する (リスト) --- */
@GetMapping("/{mid}/dones")
List<ToDo> getDoneList(@PathVariable String mid) {
return todoService.getDoneList(mid);
}
/* --- U: ToDoを完了する --- */
@PutMapping("/{mid}/todos/{seq}/done")
ToDo done(@PathVariable String mid, @PathVariable Lo...
return todoService.done(mid, seq);
}
/* --- U: ToDoを更新する --- */
@PutMapping("/{mid}/todos/{seq}")
ToDo updateToDo(@PathVariable String mid, @PathVaria...
return todoService.updateToDo(mid, seq, form);
}
/* --- D: ToDoを削除する --- */
@DeleteMapping("/{mid}/todos/{seq}")
boolean deleteToDo(@PathVariable String mid, @PathVa...
todoService.deleteToDo(mid, seq);
return true;
}
/*--------------------- エラーハンドラー -----------...
/*
* 本当は@RestControllerAdviceにまとめて書きたいが,...
* Controllerに書いている.
*/
@ExceptionHandler(ToDoAppException.class)
public ResponseEntity<Object> handleToDoException(To...
HttpStatus status;
switch (ex.getCode()) {
// 存在しない系例外
case ToDoAppException.NO_SUCH_MEMBER_EXISTS:
case ToDoAppException.NO_SUCH_TODO_EXISTS:
status = HttpStatus.NOT_FOUND;
break;
// パラメタ異常系例外
case ToDoAppException.MEMBER_ALREADY_EXISTS:
case ToDoAppException.INVALID_MEMBER_INFO:
case ToDoAppException.INVALID_TODO_INFO:
status = HttpStatus.BAD_REQUEST;
break;
// 認可失敗系例外
case ToDoAppException.INVALID_MEMBER_OPERATI...
case ToDoAppException.INVALID_TODO_OPERATION:
status = HttpStatus.FORBIDDEN;
break;
default:
status = HttpStatus.INTERNAL_SERVER_ERROR;
}
return new ResponseEntity<>(ex, status);
}
/* -- バリデーション失敗 -- */
@ExceptionHandler(MethodArgumentNotValidException.cl...
public ResponseEntity<Object> handleMethodArgumentNo...
return new ResponseEntity<>(ex, HttpStatus.BAD_R...
}
/* -- その他の例外 -- */
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleException(Except...
return new ResponseEntity<>(ex, HttpStatus.INTER...
}
}
解説
- RESTコントローラを定義するために,@RestControllerを付与...
- 各メソッドの中身は,サービスをそのままラップしているだけ
- フォームは@ModelAttributeではなく,@RequestBody で受ける
--
- バリデーションは同様に@Validated をつけるだけ
- メソッドの戻り値は,自動的にJSONオブジェクトに変換され...
- 例外処理を同じクラス内に書いている
-- 本来は,別クラスの@RestControllerAdviceを作りたいが,@...
** POSTMANで試す [#z665cb3b]
*** ToDoの取得 [#xb96c261]
GETでエンドポイントにリクエストする
- &attachref(api_get_todos.png);
*** ToDoの作成 [#t4bf8014]
POSTでエンドポイントにリクエストする
- フォームは,BODY->raw->JSONでJSON形式で渡す
- &attachref(api_post_todos.png);
*** ToDoの更新 [#ted2ec89]
自分で試してみよう
*** ToDoの削除 [#c4f31a13]
自分で試してみよう
終了行:
[[第3回]]
* REST API [#k72e7252]
- テキストはパワーポイントを参照のこと
** ToDo管理アプリにWeb-APIを実装する [#vc9829bb]
*** やりたいこと [#de855ec6]
- ToDo管理のためのRESTfulなAPIを作成する
- POST/GET/PUT/DELTE をそれぞれ CRUDに対応させる
- フォームはJSONで送る
-- @ModelAttributeではなく,@RequestBody で受けること
*** API仕様 [#y966b67b]
|操作|API呼び出し|戻り値|h
|ToDo作成|POST /api/{uid}/todos {"title": "タイトル"}|作...
|ToDo取得|GET /api/{uid}/todos/{seq}|指定したToDoオブジェ...
|ToDo取得|GET /api/{uid}/todos |そのユーザのToDoリスト|
|ToDo取得|GET /api/{uid}/dones |そのユーザのDoneリスト|
|ToDo更新|PUT /api/{uid}/todos/{seq}/done|完了したToDoオ...
|ToDo更新|PUT /api/{uid}/todos/{seq} {"title":"変更するタ...
|ToDo削除|DELETE /api/{uid}/todos/{seq}|true|
*** RESTController - RESTコントローラ [#x3611e1a]
- controller/ToDoRestController
package jp.ac.kobe_u.cs.itspecialist.todoapp.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Auto...
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validat...
import org.springframework.web.bind.MethodArgumentNotVal...
import org.springframework.web.bind.annotation.DeleteMap...
import org.springframework.web.bind.annotation.Exception...
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVaria...
import org.springframework.web.bind.annotation.PostMappi...
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBo...
import org.springframework.web.bind.annotation.RequestMa...
import org.springframework.web.bind.annotation.RestContr...
import jp.ac.kobe_u.cs.itspecialist.todoapp.dto.ToDoForm;
import jp.ac.kobe_u.cs.itspecialist.todoapp.entity.ToDo;
import jp.ac.kobe_u.cs.itspecialist.todoapp.exception.To...
import jp.ac.kobe_u.cs.itspecialist.todoapp.service.Memb...
import jp.ac.kobe_u.cs.itspecialist.todoapp.service.ToDo...
/**
* ToDoの操作,CRUDを行うAPI
*/
@RestController
@RequestMapping("/api")
public class ToDoRestController {
@Autowired
ToDoService todoService;
@Autowired
MemberService memberService;
/* --- C: ToDoを作成する --- */
@PostMapping("/{mid}/todos")
ToDo createToDo(@PathVariable String mid, @Validated...
return todoService.createToDo(mid, form);
}
/* --- R: ToDoを取得する (1件) --- */
@GetMapping("/{mid}/todos/{seq}")
ToDo getToDoList(@PathVariable String mid, @PathVari...
return todoService.getToDo(seq);
}
/* --- R: ToDoを取得する (リスト) --- */
@GetMapping("/{mid}/todos")
List<ToDo> getToDoList(@PathVariable String mid) {
return todoService.getToDoList(mid);
}
/* --- R: Doneを取得する (リスト) --- */
@GetMapping("/{mid}/dones")
List<ToDo> getDoneList(@PathVariable String mid) {
return todoService.getDoneList(mid);
}
/* --- U: ToDoを完了する --- */
@PutMapping("/{mid}/todos/{seq}/done")
ToDo done(@PathVariable String mid, @PathVariable Lo...
return todoService.done(mid, seq);
}
/* --- U: ToDoを更新する --- */
@PutMapping("/{mid}/todos/{seq}")
ToDo updateToDo(@PathVariable String mid, @PathVaria...
return todoService.updateToDo(mid, seq, form);
}
/* --- D: ToDoを削除する --- */
@DeleteMapping("/{mid}/todos/{seq}")
boolean deleteToDo(@PathVariable String mid, @PathVa...
todoService.deleteToDo(mid, seq);
return true;
}
/*--------------------- エラーハンドラー -----------...
/*
* 本当は@RestControllerAdviceにまとめて書きたいが,...
* Controllerに書いている.
*/
@ExceptionHandler(ToDoAppException.class)
public ResponseEntity<Object> handleToDoException(To...
HttpStatus status;
switch (ex.getCode()) {
// 存在しない系例外
case ToDoAppException.NO_SUCH_MEMBER_EXISTS:
case ToDoAppException.NO_SUCH_TODO_EXISTS:
status = HttpStatus.NOT_FOUND;
break;
// パラメタ異常系例外
case ToDoAppException.MEMBER_ALREADY_EXISTS:
case ToDoAppException.INVALID_MEMBER_INFO:
case ToDoAppException.INVALID_TODO_INFO:
status = HttpStatus.BAD_REQUEST;
break;
// 認可失敗系例外
case ToDoAppException.INVALID_MEMBER_OPERATI...
case ToDoAppException.INVALID_TODO_OPERATION:
status = HttpStatus.FORBIDDEN;
break;
default:
status = HttpStatus.INTERNAL_SERVER_ERROR;
}
return new ResponseEntity<>(ex, status);
}
/* -- バリデーション失敗 -- */
@ExceptionHandler(MethodArgumentNotValidException.cl...
public ResponseEntity<Object> handleMethodArgumentNo...
return new ResponseEntity<>(ex, HttpStatus.BAD_R...
}
/* -- その他の例外 -- */
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleException(Except...
return new ResponseEntity<>(ex, HttpStatus.INTER...
}
}
解説
- RESTコントローラを定義するために,@RestControllerを付与...
- 各メソッドの中身は,サービスをそのままラップしているだけ
- フォームは@ModelAttributeではなく,@RequestBody で受ける
--
- バリデーションは同様に@Validated をつけるだけ
- メソッドの戻り値は,自動的にJSONオブジェクトに変換され...
- 例外処理を同じクラス内に書いている
-- 本来は,別クラスの@RestControllerAdviceを作りたいが,@...
** POSTMANで試す [#z665cb3b]
*** ToDoの取得 [#xb96c261]
GETでエンドポイントにリクエストする
- &attachref(api_get_todos.png);
*** ToDoの作成 [#t4bf8014]
POSTでエンドポイントにリクエストする
- フォームは,BODY->raw->JSONでJSON形式で渡す
- &attachref(api_post_todos.png);
*** ToDoの更新 [#ted2ec89]
自分で試してみよう
*** ToDoの削除 [#c4f31a13]
自分で試してみよう
ページ名: