これは、REST の概要の最後の部分です。前のパートでは、以下について説明しました。
プロジェクトの作成
このセクションでは、Spring Boot を使用して小さな RESTful アプリケーションを作成します。私たちのアプリケーションは、概要の前の部分の例から、顧客に対して CRUD (作成、読み取り、更新、削除) 操作を実装します。まず、メニューから新しい Spring Boot アプリケーションを作成します: [ファイル] -> [新規] -> [プロジェクト]... 開いたウィンドウで、[Spring Initializr] を選択し、プロジェクト SDK を指定します。 [次へ] ボタンをクリックします。次のウィンドウで、プロジェクトの種類として「Maven プロジェクト」を指定し、「グループ」と「アーティファクト」を指定します。 「次へ」ボタンをクリックします。次のウィンドウでは、プロジェクトに必要な Spring Framework コンポーネントを選択する必要があります。Spring Web で十分です。 「次へ」ボタンをクリックします。あとは、プロジェクトの名前とファイル システム内の場所を指定するだけです。 [完了] ボタンをクリックします。プロジェクトが作成され、その構造が確認できます。IDEA は Maven デプロイメント記述子 (pom.xml) とアプリケーションのメイン クラス (RestExampleApplication
) を生成しました。見た目は次のとおりです。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.codegym.lessons/groupId>
<artifactId>rest_example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest_example</name>
<description>REST example project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
残りの例アプリケーション:
@SpringBootApplication
public class RestExampleApplication {
public static void main(String[] args) {
SpringApplication.run(RestExampleApplication.class, args);
}
}
REST機能の作成
私たちのアプリケーションは顧客管理システムです。したがって、最初に行う必要があるのは、顧客エンティティを作成することです。これは POJO (Plain Old Java Object) クラスになります。model
パッケージ内にパッケージを作成しますcom.codegym.lessons.rest_example
。パッケージ内でmodel
、以下を作成しますCustomer
。
public class Customer {
private Integer id;
private String name;
private String email;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
このサービスは、顧客に対して CRUD 操作を実装します。次のステップは、これらの操作を実装するサービスを作成することです。パッケージではcom.codegym.lessons.rest_example
、service
パッケージを作成します。そしてその中にCustomerService
インターフェースを作成します。コメント付きのインターフェイス コードは次のとおりです。
public interface CustomerService {
/**
* Creates a new customer
* @param customer - Customer to be created
*/
void create(Customer customer);
/**
* Returns a list of all existing customers
* @return List of customers
*/
List<Customer> readAll();
/**
* Returns a customer based on its ID
* @param id - Customer ID
* @return - Customer object with the given ID
*/
Customer read(int id);
/**
* Updates the customer with the given ID,
* according to the passed customer
* @param customer - Customer to use to update the data
* @param id - ID of the customer you want to update
* @return - true if the data has been updated, otherwise false
*/
boolean update(Customer customer, int id);
/**
* Deletes the customer with the given ID
* @param id - ID of the customer to be deleted
* @return - true if the customer was deleted, otherwise false
*/
boolean delete(int id);
}
次に、このインターフェイスを実装する必要があります。今、Map<Integer, Customer>
私たちの顧客を保管します。マップのキーは顧客 ID になり、値は顧客自体になります。これは、この例が実際のデータベースの操作の詳細で過負荷にならないようにするために行われます。ただし、将来的には、実際のデータベースに接続できるようにするインターフェイスの別の実装を作成できるようになります。パッケージ内でservice
、インターフェイスの実装を作成しますCustomerService
。
@Service
public class CustomerServiceImpl implements CustomerService {
// Customer repository
private static final Map<Integer, Customer> CUSTOMER_REPOSITORY_MAP = new HashMap<>();
// Variable for generating a customer ID
private static final AtomicInteger CUSTOMER_ID_HOLDER = new AtomicInteger();
@Override
public void create(Customer customer) {
final int customerId = CUSTOMER_ID_HOLDER.incrementAndGet();
customer.setId(customerId);
CUSTOMER_REPOSITORY_MAP.put(customerId, customer);
}
@Override
public List<Customer> readAll() {
return new ArrayList<>(CUSTOMER_REPOSITORY_MAP.values());
}
@Override
public Customer read(int id) {
return CUSTOMER_REPOSITORY_MAP.get(id);
}
@Override
public boolean update(Customer customer, int id) {
if (CUSTOMER_REPOSITORY_MAP.containsKey(id)) {
customer.setId(id);
CUSTOMER_REPOSITORY_MAP.put(id, customer);
return true;
}
return false;
}
@Override
public boolean delete(int id) {
return CUSTOMER_REPOSITORY_MAP.remove(id) != null;
}
}
注釈@Service
は、このクラスがサービスであることを Spring に伝えます。これは、ビジネス アプリケーション ロジックを実装する特別なタイプのクラスです。その後、このアノテーションのおかげで、Spring は依存性注入を使用して、必要なすべての場所にこのクラスのインスタンスを提供します。次はコントローラーを作成します。これは、エンドポイント (URI) に送信されるクライアント要求を処理するロジックを実装する特別なクラスです。これらすべてを明確にするために、このクラスを段階的に作成します。まず、クラス自体を作成し、依存関係を追加しますCustomerService
。
@RestController
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
}
アノテーションについて説明しましょう。 @RestController は、このクラスが REST コントローラーであることを Spring に伝えます。言い換えれば、このクラスはクライアント要求を処理するためのロジックを実装します。 @Autowired は、ここに依存関係を追加する必要があることを Spring に伝えます。CustomerService
インターフェイスをコンストラクターに渡します。先ほど、このサービスの実装にアノテーションを付けました@Service
。これで、Spring はこの実装のインスタンスをコントローラーのコンストラクターに渡すことができるようになります。次に、CRUD 操作を処理するための各コントローラー メソッドを実装します。作成操作から始めましょう。これを行うには、次のcreate
メソッドを作成します。
@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
customerService.create(customer);
return new ResponseEntity<>(HttpStatus.CREATED);
}
このメソッドを分析してみましょう。 @PostMapping(value = "/customers")
これは、このメソッドがアドレス「/customers」に送信された POST リクエストを処理することを意味します。このメソッドは を返しますResponseEntity<?>
。A は、ResponseEntity
応答を返すための特別なクラスです。後で、これを使用して HTTP ステータス コードをクライアントに返します。メソッドには@RequestBody Customer customer
パラメータがあります。このパラメータの値はリクエスト本文から取得されます。注釈@RequestBody
はこれを示しています。create()
メソッドの本体内で、以前に作成したサービスのメソッドを呼び出し、パラメーターで受け取ったカスタマー コントローラーに渡します。ResponseEntity
次に、新しいオブジェクトを作成し、対応するHttpStatus
enum フィールドをそれに渡すことで、「201 Created」ステータスを返します。次に実装していきます。read
操作: まず、利用可能なすべての顧客のリストを取得する操作を実装します。
@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
final List<Customer> customers = customerService.readAll();
return customers != null && !customers.isEmpty()
? new ResponseEntity<>(customers, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
詳細に見てみましょう: @GetMapping(value = "/customers")
— ここにあるものはすべてアノテーションと似ています@PostMapping
が、ここでは GET リクエストを処理しています。今回は を返しResponseEntity<List<Customer>>
、HTTP ステータスに加えて、顧客のリストとなる応答本文も返します。Spring の REST コントローラーでは、特に指定がない限り、すべてが POJO オブジェクトと POJO オブジェクトのコレクションであり、応答本文として返され、自動的に JSON にシリアル化されます。これは私たちにぴったりです。メソッド内では、サービスを使用してすべての顧客のリストを取得します。次に、リストが null でも空でもない場合は、ResponseEntity
クラスを使用して、顧客のリストと「200 OK」HTTP ステータス コードを返します。それ以外の場合は、単に「404 Not Found」HTTP ステータス コードを返します。次に、ID を使用して顧客を取得する機能を実装します。
@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
final Customer customer = customerService.read(id);
return customer != null
? new ResponseEntity<>(customer, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
ここでの 1 つの新しい点は、パス変数です。変数は URI: で定義されますvalue = "/customers/{id}"
。中括弧で囲んで示します。int
そして、それをアノテーションを使用してメソッドのパラメータとして受け取ります@PathVariable(name = "id")
。このメソッドは、 の形式で URI に送信されたリクエストを受け入れます/customers/{id}
。 は{id}
任意の数値を表します。この値は、変数を介してint id
メソッドのパラメーターに渡されます。本体では、Customer
サービスを使用してオブジェクトを取得し、受信したid
. 次に、リストから類推して、「200 OK」ステータスとオブジェクトCustomer
自体を返すか、システムにそのオブジェクトを持つ顧客がいない場合は単純に「404 Not Found」ステータスを返しますid
。さらに、更新と削除という 2 つの操作を実装する必要があります。これらのメソッドのコードは次のとおりです。
@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
final boolean updated = customerService.update(customer, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = customerService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
これらのメソッドには本質的に新しいことはないため、詳細な説明は省略します。唯一言及する価値があるのは、update()
メソッドが PUT リクエスト (@PutMapping
アノテーション) を処理し、delete()
メソッドが DELETE リクエスト (DeleteMapping
アノテーション) を処理することです。コントローラーの完全なコードは次のとおりです。
@RestController
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
customerService.create(customer);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
final List<Customer> customers = customerService.readAll();
return customers != null && !customers.isEmpty()
? new ResponseEntity<>(customers, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
final Customer customer = customerService.read(id);
return customer != null
? new ResponseEntity<>(customer, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
final boolean updated = customerService.update(customer, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = customerService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
}
その結果、プロジェクトの構造は次のようになります。
立ち上げとテスト
アプリケーションを開始するには、クラスmain()
内のメソッドを実行するだけですRestExampleApplication
。ただし、RESTful Web サービスをテストするには、追加のソフトウェアをダウンロードする必要があります。実際、GET リクエストは通常のブラウザから送信するのが非常に簡単ですが、通常のブラウザでは POST、PUT、DELETE リクエストを送信できません。心配しないでください。Postman というプログラムを使用して、HTTP リクエストを送信できます。ここからダウンロードできます。Postman をダウンロードしてインストールした後、アプリケーションのテストを開始します。これを行うには、プログラムを開いて新しいリクエストを作成します。 左上隅にある「新規」ボタンをクリックします。次に、「リクエスト」を選択します。 次に、名前を付けて保存します。次に、POST リクエストをサーバーに送信して、最初の顧客を作成してみましょう。 このようにして複数の顧客を生み出します。次に、リクエスト タイプを GET に変更し、リクエストをサーバーに送信します。
まとめ
おめでとう!REST については十分に説明しました。膨大な量の資料がありましたが、お役に立てば幸いです。-
RESTとは何かを学びました。
-
REST がどのようにして誕生したかについて学びました。
-
このアーキテクチャ スタイルの制限とその背後にある原則について話しました。
- クライアントサーバーアーキテクチャ
- ステートレス
- キャッシング
- 均一なインターフェース
- レイヤー
- コードオンデマンド (オプション)
-
REST によってもたらされる利点を調査しました
-
サーバーとクライアントが HTTP プロトコルを介してどのように相互作用するかを詳細に調査しました。
-
リクエストとレスポンスを詳しく調べました。私たちはそれらの構成部分を分析しました。
-
最後に、Spring Boot を使用して独自の小さな RESTful アプリケーションを作成することで、実践的な経験を積みました。そして、Postman を使用してテストする方法も学びました。
宿題
次のことを試してください。- 上記の説明に従って、独自の Spring Boot プロジェクトを作成し、レッスンと同じロジックを実装します。すべてを正確に繰り返します。
- アプリケーションを起動します。
- Postman (またはリクエストを送信するための他のツール (curl など)) をダウンロードして構成します。
- レッスンで説明したのと同じ方法で POST リクエストと GET リクエストをテストします。
- PUT リクエストと DELETE リクエストを自分でテストしてください。
GO TO FULL VERSION