Java入門 / コード生成AI

【Gemini Code Assist】REST APIを作成する | VS Code + Gemini Code Assist で Spring Boot アプリケーション(1)

2025.05.16

前回までの記事では、VS Code 上で Gemini Code Assist を利用して Java のコーディングを行う方法について説明しました。当記事では、さらに Spring Boot 拡張を追加して、Gemini Code Assist を用いて簡単な Web アプリケーションを作成する方法について解説します。

前回までの Gemini Code Assist の記事
 VS Code + Gemini Code Assist で Java プログラミング(1)環境構築
 VS Code + Gemini Code Assist で Java プログラミング(2)機能の利用

Spring Boot 拡張機能のインストール

Spring Boot Extension Pack

まず VS Code で Spring Boot プロジェクトを作成するために、Spring Boot 関連の拡張機能をまとめた「Spring Boot Extension Pack」をインストールします。

他の拡張機能と同様に、マーケットプレースで「Spring Boot Extension Pack」を検索して、VMWare から提供されているものをインストールしてください。

Spring Boot Extension Pack

拡張機能の発行者(VMWare)を信用するか確認メッセージが出た場合は、「Trust Publishers & Install」をクリックしてください。


Spring Boot Extension Pack では、「Spring Boot Tools」「Spring Boot Dashboard」「Spring Initializr Java Support」の3つの拡張機能がインストールされます。

Spring Boot プロジェクトの作成

Spring Initializr でプロジェクトを作成

まず、プロジェクトを作成するフォルダを開き、以前の記事(VS Code + Gemini Code Assist で Java プログラミング(1)環境構築)と同様に Java のプロジェクトを作成します。


Spring Initializr Java Support 拡張機能をインストール後の場合、プロジェクトの作成時に「Spring Boot」が選択可能となっていますので、これを選択して進めます。


Maven または Gradle の選択では Maven Project を選択します。(前々回の記事内の環境構築で Maven 拡張機能をインストール済)


Spring Boot のバージョンを選択します。今回は 3.4.5 を選択します。
※ Spring Boot 3.3 、3.4 では Java 17 以降のバージョンが必要となります。インストールされていない場合は、事前に Java 17 以降のバージョンを追加しておく必要があります。


開発言語の選択では「Java」を選択します。


プロジェクトのグループIDを入力します。この入力がパッケージ名として利用されるため、特に利用するドメインなどがなければ、初期値の「com.example」のまま進めてください。


プロジェクト名を入力します。特に指定がなければ、初期値の「demo」のまま進めてください。
この場合、先ほど指定したグループIDとあわせた「com.example.demo」が作成するプロジェクトの基本パッケージ名となります。


動作方式(Jar方式、War方式)を選択します。特に指定がなければ初期値(Jar)のまま進めます。


Javaのバージョンを指定します。今回は Java 21 を選択しました。


必要に応じて、追加したいライブラリを選択します。Lombok などのライブラリを使用したい場合はここで追加してください。今回は特に追加せずに進めてOKです。


ライブラリを選択したら(または選択しない場合も)、入力欄にフォーカスして Enter キーを押下してフォルダの選択へ進みます。表示されたダイアログで、プロジェクトのフォルダの作成先を選択して、最後に「Generate into this folder」をクリックしてください。


フォルダを選択すると、プロジェクトが作成されます。プロジェクトのフォルダは、プロジェクト名として指定した名前で作成されます。

作成したプロジェクトを新しいウインドウ(VS Code)で開きたい場合は「Open」を、現在開いているワークスペースに追加したい場合は「Add to Workspace」をクリックしてください。


これで Spring Boot プロジェクトが追加されました。新しいプロジェクトはまだWebブラウザで表示できる内容がないので、引き続きコントローラークラスを作成します。

REST APIの作成

Spring Boot アプリケーションでは、HTMLを表示するWebアプリケーションの他にも、JSON や XML のような文字列を返却する REST API を簡単に作成することができます。

ここでは、最も簡単に作成できる REST API のコントローラーを Gemini Code Assist で生成して動作確認を行い、さらに実際に JSON 形式でデータを返却するアプリケーションを作成してみます。

(参考)REST API の作成 - Spring 公式ガイド

RestControllerクラスの作成

クラスの作成

動作確認用に、JSON 形式の文字列を返却するコントローラークラスを作成します。

Gemini Code Assist のチャットスペースを開き、最初にプロンプトでプロジェクトのフォルダーのパスを認識させます。これは、このあとファイルを Gemini Code Assist 拡張機能で直接作成させるために必要になります。

@demo このフォルダーのパス「C:\VSCode\Java\GeminiCodeAssist\demo」を、プロジェクトのルートフォルダーとして認識してください。

※プロジェクト名は「demo」で作成されているものとします。違う名前でプロジェクトを作成した場合は、その名前と置き換えてお読みください。
※フォルダーのパス(C:\VSCode\Java\GeminiCodeAssist\demo の部分)は、実際にアプリケーションを作成したフォルダーを指定してください。

太字の「@demo」の部分は、チャットの入力欄に「@」を入力して、「Folders」の中から選択します。直接文字列で打ち込んでも無効となる場合がありますので注意してください。


プロジェクトのルートフォルダを認識したと返答されたら、次にブラウザからアクセスするためのコントローラークラスを作成するように指示します。

このプロジェクトの src/main/java/com/example/demo/controller フォルダに、JSON文字列を返すコントローラークラス DemoController を作成してください。作成するクラスには、 URI "/demo" に対して、JSON文字列を返すメソッドを作成してください。


チャットスペースに提示されるコードの内容を確認を行い、ファイル名の右にあるチェックアイコンをクリックして、ファイルを保存します。

ファイルの保存先がうまく指定できない場合は、再度 Gemini Code Assist にプロジェクトのルートフォルダを認識させてから、同じプロンプトを入力してみてください。


反映したファイルは、エディタ上で Ctrl + S キーを押下して保存する必要がありますのでご注意ください。保存時に、指定したパス、ファイル名でコントローラークラスが作成されます。


DemoController.java を保存したら、Spring Boot アプリケーションを起動して動作確認してみましょう。

動作確認

左メニューに表示されているアイコンから「Spring Boot Dashboard」を開き、Spring Boot アプリケーションを起動します。

上部の「APPS」の中に表示されているプロジェクト(demo)の右側にある三角のアイコン( ▷ )をクリックして、アプリケーションを起動します。(または、プロジェクト名を右クリック → Run でも起動できます)


Spring Boot アプリケーションが起動したら、WebブラウザにURL「http://localhost:8080/demo」と入力して、作成した Controller にアクセスします。今回生成したメソッドから返却された JSON 文字列が表示されます。


確認できたら、一旦 Spring Boot アプリケーションを停止しておきましょう。アプリケーションの停止は、開始時と同じく「Spring Boot Dashboard」から対象プロジェクトの停止アイコン( )をクリックします。

JSONドキュメントの作成

実際に REST API として JSON 文字列を返却する場合、 事前に JSON ドキュメントの型を定義する必要があります。今回はカートの情報を返す JSON と、カート内の商品情報を返す JSON の内容について、Gemini Code Assist を利用して作成します。

まず、チャットスペースで作成先とファイル名を指定して、カート内商品情報の JSON ドキュメントを作成するように指示します。項目の内容はなるべくプロンプト内で具体的に提示しましょう。

このプロジェクトの src/main/resources/templates/json の中に、cartItem.json という名前で、商品ID、商品名、税込価格、数量、合計金額、商品ページへのリンクURL の5項目を持つJSONドキュメントを作成してください。項目名は英語、商品名の値は日本語でお願いします。


提示された内容を確認してファイルを保存します。項目名や、提示された内容を変更したい場合は、チャットを繰り返して内容を修正することもできます。


今回は、以下のような JSON ドキュメントが提案されました。この内容を cartItem.json として保存します。

{
  "productId": "ITEM001",
  "productName": "美味しいリンゴ",
  "priceWithTax": 108,
  "quantity": 3,
  "totalAmount": 324,
  "productPageUrl": "https://example.com/products/ITEM001"
}


同じように、カート情報についても JSON ドキュメントを作成します。この情報には、カート内の商品情報を複数保持できるように指示します。

次に、cartInfo.json という名前で、ユーザーID、送付者名、送付先名、郵便番号、送付先住所・都道府県、同・市区町村、同・番地等、同・建物名、カート内商品情報のリストを持つJSONドキュメントを作成してください。
カート内商品情報は先ほど生成した cartItem.json の内容で、全部で3商品としてください。


こちらも、提案されたコードを確認し、ファイルに反映しておきます。


cartInfo.json として提案された JSON の内容は以下の通りでした。サンプルとして提示されるデータに、実在する建物名などが含まれている場合があるため、必要に応じてチャットまたは手動で修正を行ってください。

{
  "userId": "USER789",
  "senderName": "山田 太郎",
  "recipientName": "佐藤 花子",
  "postalCode": "100-0005",
  "recipientAddressPrefecture": "東京都",
  "recipientAddressCity": "千代田区",
  "recipientAddressLine1": "丸の内1-2-3",
  "recipientAddressLine2": "パシフィックセンチュリープレイス丸の内 20F",
  "items": [
    {
      "productId": "ITEM001",
      "productName": "美味しいリンゴ",
      "priceWithTax": 108,
      "quantity": 3,
      "totalAmount": 324,
      "productPageUrl": "https://example.com/products/ITEM001"
    },
    {
      "productId": "ITEM002",
      "productName": "高級バナナセット",
      "priceWithTax": 540,
      "quantity": 1,
      "totalAmount": 540,
      "productPageUrl": "https://example.com/products/ITEM002"
    },
    {
      "productId": "ITEM003",
      "productName": "旬のいちごパック",
      "priceWithTax": 756,
      "quantity": 2,
      "totalAmount": 1512,
      "productPageUrl": "https://example.com/products/ITEM003"
    }
  ]
}


これで、アプリケーションから返却する JSON の型を決めることができました。サンプルとして生成した2つのJSONファイルも、指定したフォルダに保存されています。

JSON用オブジェクトの作成

Spring Boot の RestController クラスでは、キーと値を持つ Map 型のインターフェイスや、Java Bean など getter/setter メソッドが準備されたオブジェクトを、JSON 文字列に変換して返却することができます。

ここでは、上記で作成した JSON ドキュメントから、対応する情報を格納するための Java のクラスを作成してみます。まず、cartItem.json の内容から CartItem.java の内容を生成するようにプロンプトを入力します。

このプロジェクトの src/main/java/com/example/demo/bean フォルダに、cartItem.json に対応する項目を格納できる Java Bean クラス CartItem.java を作成してください。
各メンバ変数はnullに対応できるようにしてください。
各変数、getter/setter、クラスには日本語でコメントを追加してください。


プロンプトでは、各項目を null にも対応可能としたり、クラス、変数、 getter/setter メソッドにコメントを付与するように指示しています。

Gemini Code Assist から提示された内容を確認し、ファイルを保存します。


今回は以下の内容でコードが提案されました。クラスの用途を想定して、toStringメソッドがオーバーライドされています。引数で直接メンバ変数を設定するコンストラクタも作成されていますね。

package com.example.demo.bean;

/**
 * カート内の個々の商品情報を格納するBeanクラスです。
 * cartItem.json の各項目に対応します。
 */
public class CartItem {

    /**
     * 商品ID
     * 例: "ITEM001"
     */
    private String productId;

    /**
     * 商品名
     * 例: "美味しいリンゴ"
     */
    private String productName;

    /**
     * 税込価格
     * 例: 108
     */
    private Integer priceWithTax; // null許容のためIntegerを使用

    /**
     * 数量
     * 例: 3
     */
    private Integer quantity; // null許容のためIntegerを使用

    /**
     * 合計金額 (単価 * 数量)
     * 例: 324
     */
    private Integer totalAmount; // null許容のためIntegerを使用

    /**
     * 商品ページへのリンクURL
     * 例: "https://example.com/products/ITEM001"
     */
    private String productPageUrl;

    /**
     * デフォルトコンストラクタ
     */
    public CartItem() {
    }

    /**
     * 全てのフィールドを初期化するコンストラクタ
     * @param productId 商品ID
     * @param productName 商品名
     * @param priceWithTax 税込価格
     * @param quantity 数量
     * @param totalAmount 合計金額
     * @param productPageUrl 商品ページURL
     */
    public CartItem(String productId, String productName, Integer priceWithTax, Integer quantity, Integer totalAmount, String productPageUrl) {
        this.productId = productId;
        this.productName = productName;
        this.priceWithTax = priceWithTax;
        this.quantity = quantity;
        this.totalAmount = totalAmount;
        this.productPageUrl = productPageUrl;
    }

    // --- GetterおよびSetterメソッド ---

    /** @return 商品ID */
    public String getProductId() { return productId; }
    /** @param productId 商品ID */
    public void setProductId(String productId) { this.productId = productId; }

    /** @return 商品名 */
    public String getProductName() { return productName; }
    /** @param productName 商品名 */
    public void setProductName(String productName) { this.productName = productName; }

    /** @return 税込価格 */
    public Integer getPriceWithTax() { return priceWithTax; }
    /** @param priceWithTax 税込価格 */
    public void setPriceWithTax(Integer priceWithTax) { this.priceWithTax = priceWithTax; }

    /** @return 数量 */
    public Integer getQuantity() { return quantity; }
    /** @param quantity 数量 */
    public void setQuantity(Integer quantity) { this.quantity = quantity; }

    /** @return 合計金額 */
    public Integer getTotalAmount() { return totalAmount; }
    /** @param totalAmount 合計金額 */
    public void setTotalAmount(Integer totalAmount) { this.totalAmount = totalAmount; }

    /** @return 商品ページURL */
    public String getProductPageUrl() { return productPageUrl; }
    /** @param productPageUrl 商品ページURL */
    public void setProductPageUrl(String productPageUrl) { this.productPageUrl = productPageUrl; }

    @Override
    public String toString() {
        return "CartItem{" +
                "productId='" + productId + '\'' +
                ", productName='" + productName + '\'' +
                ", priceWithTax=" + priceWithTax +
                ", quantity=" + quantity +
                ", totalAmount=" + totalAmount +
                ", productPageUrl='" + productPageUrl + '\'' +
                '}';
    }
}


もし Gemini Code Assist が自動でJSONファイルの内容を読み込まないときは、ファイルを指定して内容に名前を紐づけて利用したり、ファイルの内容を直接プロンプトに含めて送信することで、その情報を利用して指示を出すことができます。

例1)
@cartItem.json このファイルの内容を「カート商品情報」として一時的に記憶してください。

例2)
以下のJSONファイルはカートの商品情報です。これを元に、各項目を格納できるJava Beanクラスを作成してください。
{
  "productId": "P001",
"productName": "美味しいリンゴ",
…(※以下略)
}


カート情報についても cartInfo.json の内容からクラスを生成します。カート情報内に保持するカート商品情報は複数個保持できるように List 型を指定して指示しています。

同じように src/main/java/com/example/demo/bean フォルダに、cartInfo.jsonから各項目を格納できるBeanクラス CartInfo.java を作成してください。カート内商品情報は CartItem のListとしてください。


こちらも同様に、提案されたコードをファイルに保存します。


提案されたコードは以下の内容でした。こちらも引数付のコンストラクタや、toStringメソッドのオーバーライドが生成されています。toStringメソッドではカート内商品は点数しか表示されないため、もう少し工夫ができそうです。

package com.example.demo.bean;

import java.util.List;

/**
 * カート全体の情報を格納するBeanクラスです。
 * cartInfo.json の各項目に対応します。
 */
public class CartInfo {

    /**
     * ユーザーID
     * 例: "USER789"
     */
    private String userId;

    /**
     * 送付者名
     * 例: "山田 太郎"
     */
    private String senderName;

    /**
     * 送付先名
     * 例: "佐藤 花子"
     */
    private String recipientName;

    /**
     * 郵便番号
     * 例: "100-0005"
     */
    private String postalCode;

    /**
     * 送付先住所・都道府県
     * 例: "東京都"
     */
    private String recipientAddressPrefecture;

    /**
     * 送付先住所・市区町村
     * 例: "千代田区"
     */
    private String recipientAddressCity;

    /**
     * 送付先住所・番地等
     * 例: "丸の内1-2-3"
     */
    private String recipientAddressLine1;

    /**
     * 送付先住所・建物名 (任意)
     * 例: "パシフィックセンチュリープレイス丸の内 20F"
     */
    private String recipientAddressLine2;

    /**
     * カート内商品情報のリスト
     */
    private List<CartItem> items;

    /**
     * デフォルトコンストラクタ
     */
    public CartInfo() {
    }

    /**
     * 全てのフィールドを初期化するコンストラクタ
     * @param userId ユーザーID
     * @param senderName 送付者名
     * @param recipientName 送付先名
     * @param postalCode 郵便番号
     * @param recipientAddressPrefecture 送付先住所・都道府県
     * @param recipientAddressCity 送付先住所・市区町村
     * @param recipientAddressLine1 送付先住所・番地等
     * @param recipientAddressLine2 送付先住所・建物名
     * @param items カート内商品リスト
     */
    public CartInfo(String userId, String senderName, String recipientName, String postalCode,
                    String recipientAddressPrefecture, String recipientAddressCity,
                    String recipientAddressLine1, String recipientAddressLine2, List<CartItem> items) {
        this.userId = userId;
        this.senderName = senderName;
        this.recipientName = recipientName;
        this.postalCode = postalCode;
        this.recipientAddressPrefecture = recipientAddressPrefecture;
        this.recipientAddressCity = recipientAddressCity;
        this.recipientAddressLine1 = recipientAddressLine1;
        this.recipientAddressLine2 = recipientAddressLine2;
        this.items = items;
    }

    // --- GetterおよびSetterメソッド ---

    /** @return ユーザーID */
    public String getUserId() { return userId; }
    /** @param userId ユーザーID */
    public void setUserId(String userId) { this.userId = userId; }

    /** @return 送付者名 */
    public String getSenderName() { return senderName; }
    /** @param senderName 送付者名 */
    public void setSenderName(String senderName) { this.senderName = senderName; }

    /** @return 送付先名 */
    public String getRecipientName() { return recipientName; }
    /** @param recipientName 送付先名 */
    public void setRecipientName(String recipientName) { this.recipientName = recipientName; }

    /** @return 郵便番号 */
    public String getPostalCode() { return postalCode; }
    /** @param postalCode 郵便番号 */
    public void setPostalCode(String postalCode) { this.postalCode = postalCode; }

    /** @return 送付先住所・都道府県 */
    public String getRecipientAddressPrefecture() { return recipientAddressPrefecture; }
    /** @param recipientAddressPrefecture 送付先住所・都道府県 */
    public void setRecipientAddressPrefecture(String recipientAddressPrefecture) { this.recipientAddressPrefecture = recipientAddressPrefecture; }

    /** @return 送付先住所・市区町村 */
    public String getRecipientAddressCity() { return recipientAddressCity; }
    /** @param recipientAddressCity 送付先住所・市区町村 */
    public void setRecipientAddressCity(String recipientAddressCity) { this.recipientAddressCity = recipientAddressCity; }

    /** @return 送付先住所・番地等 */
    public String getRecipientAddressLine1() { return recipientAddressLine1; }
    /** @param recipientAddressLine1 送付先住所・番地等 */
    public void setRecipientAddressLine1(String recipientAddressLine1) { this.recipientAddressLine1 = recipientAddressLine1; }

    /** @return 送付先住所・建物名 */
    public String getRecipientAddressLine2() { return recipientAddressLine2; }
    /** @param recipientAddressLine2 送付先住所・建物名 */
    public void setRecipientAddressLine2(String recipientAddressLine2) { this.recipientAddressLine2 = recipientAddressLine2; }

    /** @return カート内商品リスト */
    public List<CartItem> getItems() { return items; }
    /** @param items カート内商品リスト */
    public void setItems(List<CartItem> items) { this.items = items; }

    @Override
    public String toString() {
        return "CartInfo{" +
                "userId='" + userId + '\'' +
                ", senderName='" + senderName + '\'' +
                ", recipientName='" + recipientName + '\'' +
                ", postalCode='" + postalCode + '\'' +
                ", recipientAddressPrefecture='" + recipientAddressPrefecture + '\'' +
                ", recipientAddressCity='" + recipientAddressCity + '\'' +
                ", recipientAddressLine1='" + recipientAddressLine1 + '\'' +
                ", recipientAddressLine2='" + recipientAddressLine2 + '\'' +
                ", items=" + (items != null ? items.size() + " items" : "null") +
                '}';
    }
}


これで、返却する JSON に対応するデータを格納するためのクラスが準備できました。


今回は JSON ドキュメントの定義から Gemini Code Assist で生成しましたが、事前にAPIの型が定義された仕様書などがあれば、その情報を読み込ませることで、簡単に Java のクラスが生成できるでしょう。

JSONを返却するコントローラーメソッドの作成

それでは、実際にこれらのクラスを利用して、コントローラークラスに JSON を返却するメソッドを追加します。

指定したURIに対応するメソッドの作成

最初に作成したコントローラークラス(DemoController.java)に、JSON 文字列を返すためのメソッドを追加します。

アクセスするための URI、追加するメソッドに引き渡すパラメーター、パラメーターの指定がない場合の動作なども、プロンプトで指定します。

@DemoController.java ユーザーIDをパラメーターとして受け取り、CartInfo 型のJSONを返却するためのメソッドを追加してください。
URIは "cart/{userId}" として、ユーザーIDをURIからパラメーターとして受け取れるものとします。
パラメーターのユーザーIDが null または空、空白の場合は、空の CartInfo を返すようにしてください。
また、実際に返却するデータを取得するメソッドは、コントローラーのメソッドと切り分けて作成してください。


生成されたコードを確認して、ファイルに反映します。チャット欄に表示された差分の横の四角のアイコンをクリックすると、Gemini Diff エディターで確認することもできます。


データを取得するための処理(データベースや取得内容の詳細)は指定していなかったため、ダミーデータを生成して設定するように実装されていました。ひとまず、この内容で DemoController クラスへ反映、保存します。

ファイルからデータを取得するメソッドの作成

上記で作成したメソッドでは、プログラムコードの中で JSON に出力する内容を1つずつ設定していました。これを、 JSON ファイルを読み込んで返すように変更してみましょう。

チャットスペースでファイルとメソッドを指定して、JSON の内容をファイルから取得するように Gemini Code Assist に指示します。ファイルの読み込み時にエラーが発生した場合の動作もあわせて指示しました。

@DemoController.java fetchUserCartDataメソッドで返すダミーデータの内容を、cartInfo.json のファイルから読み込んで返すようにしてください。
但し、ファイルの読み込みに失敗したり、JSONの内容が CartInfo クラスの内容と一致しないような場合は、別メソッドでスタブデータを作成して返すようにしてください。この時、カート内の商品には3件のダミーデータを作成してください。


提示された内容を確認してファイルを保存します。ダミーデータをコード上で作成していた処理が、ファイルを読み込んで返すように修正されているのがわかります。


この内容で DemoController.java に保存し、再度 Spring Boot アプリケーションを起動して「http://localhost:8080/cart/USERID」にアクセスします。(USERID の箇所は ”0001" など任意の文字列で構いません)


JSON の文字列がWebブラウザに表示されました。userIdはパラメーターで指定した値、それ以外の項目は cartInfo.json から値が取得されているのがわかります。

まとめ

いかがでしたでしょうか。実際の業務アプリケーションでは、表示する内容をデータベースから取得したり、様々なチェック処理などが必要となりますが、具体的に指示することで、それらも生成することが可能です。

また、今回作成したような単純なアプリケーションに対して、パラメーターを条件にして読み取るファイルを振り分ける、などの処理もプロンプトでの指示だけで追加できるため、スマートフォンアプリなどのフロントエンド向けにテスト用APIを簡単に準備する、などといったこともできそうです。

次回は Thymeleaf テンプレートなども Gemini Code Assist で生成して、画面を持つ Spring Boot アプリケーションを作成してみます。

株式会社GSI 採用サイト

新しいこと、始めよう

あなたとともに歩を進めるWEBメディア

広告

広告