【Spring BootでREST API】#2 API作成の基本

Web

今回の目標

前回はイントロダクションとして、REST APIを作成するために必要な知識の説明をしました。こちらの内容を前提に進めていきますので、一度目を通していただきたいです。

【Spring BootでREST API】#1 イントロダクション
Spring Boot + Spring SecurityでREST APIってどう作るの?という疑問から、その作成方法について連載していきます。今回はイントロダクションとして、REST APIの実装に必要な知識についていくつか説明していきます。

今回は認証については考えず、まずは基本的なAPIの作成方法について説明していきます。

プロジェクトの作成について

プロジェクトの作成については割愛しますが、使用するのは「Spring Web」と「Spring Boot DevTools」のみです。Spring Securityは最初は使用しません。

またDB関連のものは、説明の簡略化のためにこのシリーズでは使用しません。

APIの確認方法について

特に指定はありませんが、今回はARC(Advanced REST client)を使用します。Chromeの拡張として手軽に使うことができます。

Advanced REST client
The web developers helper program to create and test custom HTTP requests.

作成するAPIについて

今回は次の商品(Product)に対するAPIを作成します。

public class Product {
  @NotBlank
  private String id;

  @NotBlank
  private String name;

  private int price;

  public Product() {}

  public Product(String id, String name, int price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }

  //Setter・Getterは省略
}
パスHttpメソッドHttpステータス説明
/api/productGET200全件取得
/api/product/{id}GET2001件取得
/api/productPOST201作成
/api/productPUT201, 204更新(存在しない場合作成)
/api/product/{id}DELETE2041件削除

Httpステータスはすべて200とするケースもあるようですが、今回は使い分けます。

また更新について、存在しない場合はエラーとする考えもあるのですが、今回はあえて作成するように実装します。

REST APIの作成

REST APIを作成するためにControllerクラスを作成します。通常のControllerでは@Controllerを付与しますが、REST APIの場合は@RestControllerを付与します。

@RestController
@RequestMapping("api/product")
public class ProductController {
  //ここにAPIの処理を定義していく
}

これにより「/api/product」にアクセスされた場合は、このControllerで処理されることになります。

通常は必要ないのですが、今回はDBを使用しないため次のような仮データをController内に用意しておきます。

private Map<String, Product> products = new HashMap<String, Product>() {
  private static final long serialVersionUID = 1L;
  {
    put("1", new Product("1", "商品A", 2000));
    put("2", new Product("2", "商品B", 3000));
    put("3", new Product("3", "商品C", 4000));
  }
};

全件取得

基本的な考え方は今までと変わりません。GETメソッドの処理なので@GetMappingを付与します。

@GetMapping
public List<Product> getAll() {
  return new ArrayList<>(products.values());
}

ここで注目してほしいのは返値です。通常のControllerの場合は、Stringで表示したいhtmlファイルやリダイレクト先を指定しました。RestControllerの場合は、返値に設定したオブジェクトをJSONに変換し、レスポンスボディに設定してくれます。

試しに作成したAPIにアクセスしてみましょう。Httpステータスは200で、レスポンスボディに取得結果が設定されていると思います。

1件取得

1件取得は全件取得とそれほど変わりはありません。該当の商品は、パスパラメーターで指定されているidで取得します。

@GetMapping("{id}")
public Product getById(@PathVariable("id") String id) {
  return products.get(id);
}

結果については割愛します。

作成

商品に必要な情報(id、name、price)がすべて送信され、またkeyの被りがないことを前提に実装します。バリデーションなどのエラー処理は次の記事で説明します。

作成はPOSTで送信されるので@PostMappingを付与します。ここでのポイントは、送信するHttpステータスが201: Createdということです。

200以外のHttpステータスを送信する場合は、@ResponseStatusを付与します。引数には該当するHttpStatus(列挙型)を設定します。

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void create(Product product) {
  products.put(product.getId(), product);
}

それでは確認のためにAPIにアクセスしてみます。Content-Typeはapplication/x-www-form-urlencodedとし、必要なデータを送信します。

Httpステータスに201が返ってくれば成功です。念のため全件取得で登録されていることを確認してみてください。

JSONの受信

Content-Typeについて、application/x-www-form-urlencodedの他にapplication/jsonを扱うAPIもよく見ます。Spring Bootでは次のように@RequestBodyを付与するだけでapplication/jsonに対応できます。

@PostMapping
@ResponseStatus(@RequestBody HttpStatus.CREATED)
public void create(Product product) {
  products.put(product.getId(), product);
}

更新

更新についても商品に必要な情報はすべて送信されるものとします。

PUTメソッドの場合は@PutMappingを付与します。更新処理が他と異なる点は、条件によって返すHttpステータスが異なることです。このような場合は@ResponseStatusは使用できません。

ではどうするのか…。

答えは次のようにResponseEntity<>を返すようにします。

@PutMapping
public ResponseEntity<Object> update(Product product) {
  HttpStatus status = products.containsKey(product.getId())
                    ? HttpStatus.NO_CONTENT : HttpStatus.CREATED;
  products.put(product.getId(), product);
  return ResponseEntity.status(status).body(null);
}

ResponseEntityにはレスポンスの内容を設定でき、それを返すことで設定したレスポンスが送信されます。今回、更新は204: No Content、作成は201: Createdとなるように設定しています。レスポンスボディは不要なのでnullとしています。

ではPOSTと同様にAPIに送信してみます。201、204のどちらも返ってくることを確認してみてください。

削除

DELETEメソッドの場合は、@DeleteMappingを付与します。その他は特に説明する必要はないと思います。

@DeleteMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable("id") String id) {
  products.remove(id);
}

結果についても割愛します。

あとがき

今回はREST APIの作成について、基本的なところを説明していきました。シンプルなものであれば結構簡単に作ることができそうですね。

ただし、実際には指定したidの商品が存在しなかったり、送信したデータに誤りがあるなどのエラー処理があると思います。次回はそのあたりを中心にやっていけたらと思っています。

 

- Spring Bootのおすすめ書籍はコチラ -

コメント

タイトルとURLをコピーしました