paint-brush
Spring Boot と Gradle を使用して新しい API を迅速に導入する方法@johnjvester
355 測定値
355 測定値

Spring Boot と Gradle を使用して新しい API を迅速に導入する方法

John Vester14m2025/03/24
Read on Terminal Reader

長すぎる; 読むには

市場投入までの時間は、あらゆるアイデアやソリューションの成否を左右します。ChatGPT、Spring Boot、Gradle、Heroku を活用して、RESTful API をいかに早く作成できるかをご覧ください。
featured image - Spring Boot と Gradle を使用して新しい API を迅速に導入する方法
John Vester HackerNoon profile picture
0-item
1-item
2-item


過去 5 年間、私は「すべてはアイデアから始まる」という言葉をオフィスの壁に掲げてきました。


私がフィットネス アプリケーション用の API コレクションの開発を開始した直後に、妻が Etsy でこの製品を見つけました。この言葉は、新しいプロジェクトの作成段階で私を駆り立てる情熱を表現しているので、とても気に入っています。これは、キャリアを 30 年経った今でも、エンジニアであることの最も好きな側面です。


この間私が学んだことは、アイデアは誰かがそれを体験する機会があって初めて意味を持つということです。アイデアが実現するまでに時間がかかりすぎると、他の人に先を越され、チャンスを逃すことになります。スタートアップ企業がアイデアをできるだけ早く市場に出すために常に競争しているのはこのためです。


アイデアをいかにして素早く実現できるかを見ていきましょう。

仮定

この記事では、シンプルに説明します。Java 17 と Spring Boot 3 を使用して RESTful API を作成します。この例では、ビルドの自動化に Gradle を使用します。


私たちが市場に投入する予定のサービス アイデアでは通常、永続性レイヤーを使用しますが、この例ではそれを脇に置いて、リポジトリ クラス内でデータを静的に定義します。


この例では、セキュリティの追加については考慮せず、この概念実証のために匿名アクセスを許可するだけです。

モチベーション引用API

私たちのアイデアがモチベーションを高める名言集の API だと仮定しましょう。できるだけ速くレースを進めるために、ChatGPT に OpenAPI 仕様を作成するように依頼しました。


数秒以内に、ChatGPT は応答を提供しました。


以下は、ChatGPT が生成した YAML 形式の OpenAPI 仕様です。


 openapi: 3.0.0 info: title: Motivational Quotes API description: An API that provides motivational quotes. version: 1.0.0 servers: - url: https://api.example.com description: Production server paths: /quotes: get: summary: Get all motivational quotes operationId: getAllQuotes responses: '200': description: A list of motivational quotes content: application/json: schema: type: array items: $ref: '#/components/schemas/Quote' /quotes/random: get: summary: Get a random motivational quote operationId: getRandomQuote responses: '200': description: A random motivational quote content: application/json: schema: $ref: '#/components/schemas/Quote' /quotes/{id}: get: summary: Get a motivational quote by ID operationId: getQuoteById parameters: - name: id in: path required: true schema: type: integer responses: '200': description: A motivational quote content: application/json: schema: $ref: '#/components/schemas/Quote' '404': description: Quote not found components: schemas: Quote: type: object required: - id - quote properties: id: type: integer quote: type: string


手動で更新する必要があったのは、 Quoteスキーマにidプロパティとquoteプロパティが必要であることを確認することだけでした。これは、最初のプロンプトで ChatGPT にこの制約を伝えるのを忘れたためです。

これで、 API ファーストアプローチを使用して新しいサービスを開発する準備が整いました。

APIファーストを使用したSpring Bootサービスの構築

この例では、 Spring Boot CLIを使用して新しいプロジェクトを作成します。Homebrew を使用して CLI をインストールする方法は次のとおりです。


 $ brew tap spring-io/tap $ brew install spring-boot

新しいSpring Bootサービスを作成する

プロジェクトをquotes呼び、次のコマンドで作成します。


 $ spring init --dependencies=web quotes


quotesフォルダの内容を調べてみましょう。


 $ cd quotes && ls -la total 72 drwxr-xr-x@ 11 jvester 352 Mar 1 10:57 . drwxrwxrwx@ 90 jvester 2880 Mar 1 10:57 .. -rw-r--r--@ 1 jvester 54 Mar 1 10:57 .gitattributes -rw-r--r--@ 1 jvester 444 Mar 1 10:57 .gitignore -rw-r--r--@ 1 jvester 960 Mar 1 10:57 HELP.md -rw-r--r--@ 1 jvester 545 Mar 1 10:57 build.gradle drwxr-xr-x@ 3 jvester 96 Mar 1 10:57 gradle -rwxr-xr-x@ 1 jvester 8762 Mar 1 10:57 gradlew -rw-r--r--@ 1 jvester 2966 Mar 1 10:57 gradlew.bat -rw-r--r--@ 1 jvester 28 Mar 1 10:57 settings.gradle drwxr-xr-x@ 4 jvester 128 Mar 1 10:57 src


次に、API ファースト アプローチを採用するために、次に示すようにbuild.gradleファイルを編集します。


 plugins { id 'java' id 'org.springframework.boot' version '3.4.3' id 'io.spring.dependency-management' version '1.1.7' id 'org.openapi.generator' version '7.12.0' } openApiGenerate { generatorName = "spring" inputSpec = "$rootDir/src/main/resources/static/openapi.yaml" outputDir = "$buildDir/generated" apiPackage = "com.example.api" modelPackage = "com.example.model" configOptions = [ dateLibrary: "java8", interfaceOnly: "true", useSpringBoot3: "true", useBeanValidation: "true", skipDefaultInterface: "true" ] } group = 'com.example' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.openapitools:jackson-databind-nullable:0.2.6' implementation 'io.swagger.core.v3:swagger-annotations:2.2.20' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } sourceSets { main { java { srcDirs += "$buildDir/generated/src/main/java" } } } compileJava.dependsOn tasks.openApiGenerate tasks.named('test') { useJUnitPlatform() }


最後に、生成された OpenAPI 仕様をopenapi.yamlとしてresources/staticフォルダーに配置します。

APIとモデルオブジェクトを生成する

IntelliJ でプロジェクトを開いた後、次のコマンドを実行して API スタブとモデル オブジェクトをビルドしました。


 ./gradlew clean build


これで、OpenAPI 仕様から作成されたapiおよびmodelオブジェクトを確認できます。QuotesAPI.java ファイルQuotesAPI.java次のとおりです。


ビジネスロジックを追加する

基本サービスが準備され、OpenAPI 契約に準拠しているので、サービスにビジネス ロジックを追加し始めます。


まず、サービスのデータを返すQuotesRepositoryクラスを作成します。前述のように、これは通常、専用の永続化レイヤーに保存されます。この例では、5 つの引用文に相当するデータをハードコーディングするだけで十分であり、集中力を維持できます。


 @Repository public class QuotesRepository { public static final List<Quote> QUOTES = List.of( new Quote() .id(1) .quote("The greatest glory in living lies not in never falling, but in rising every time we fall."), new Quote() .id(2) .quote("The way to get started is to quit talking and begin doing."), new Quote() .id(3) .quote("Your time is limited, so don't waste it living someone else's life."), new Quote() .id(4) .quote("If life were predictable it would cease to be life, and be without flavor."), new Quote() .id(5) .quote("If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success.") ); public List<Quote> getAllQuotes() { return QUOTES; } public Optional<Quote> getQuoteById(Integer id) { return Optional.ofNullable(QUOTES.stream().filter(quote -> quote.getId().equals(id)).findFirst().orElse(null)); } }


次に、 QuotesRepositoryと対話するQuotesServiceを作成します。このアプローチを採用すると、データがビジネス ロジックから分離されます。


 @RequiredArgsConstructor @Service public class QuotesService { private final QuotesRepository quotesRepository; public List<Quote> getAllQuotes() { return quotesRepository.getAllQuotes(); } public Optional<Quote> getQuoteById(Integer id) { return quotesRepository.getQuoteById(id); } public Quote getRandomQuote() { List<Quote> quotes = quotesRepository.getAllQuotes(); return quotes.get(ThreadLocalRandom.current().nextInt(quotes.size())); } }


最後に、API ファースト アプローチから生成されたQuotesApiを実装するだけです。


 @Controller @RequiredArgsConstructor public class QuotesController implements QuotesApi { private final QuotesService quotesService; @Override public ResponseEntity<List<Quote>> getAllQuotes() { return new ResponseEntity<>(quotesService.getAllQuotes(), HttpStatus.OK); } @Override public ResponseEntity<Quote> getQuoteById(Integer id) { return quotesService.getQuoteById(id) .map(quote -> new ResponseEntity<>(quote, HttpStatus.OK)) .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); } @Override public ResponseEntity<Quote> getRandomQuote() { return new ResponseEntity<>(quotesService.getRandomQuote(), HttpStatus.OK); } }


この時点で、私たちは、少数の応答のコレクションを備えた、完全に機能する Motivational Quotes API を所有しています。

最後に

Spring Boot ではspringdoc-openapi-starter-webmvc-ui依存関係を介して、Web ベースの Swagger Docs ユーザー インターフェースのオプションが提供されます。


 dependencies { ... implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.5' ... }


フレームワークを使用すると、エンジニアは簡単な注釈を使用して API を記述できますが、 resources/staticフォルダー内の既存のopenapi.yamlファイルを使用することもできます。


このアプローチは、他のいくつかの小さな構成の更新とともに、 application-properties.yamlファイルに実装できます。


 server: port: ${PORT:8080} spring: application: name: quotes springdoc: swagger-ui: path: /swagger-docs url: openapi.yaml


楽しみのために、サービスの開始時に使用するbanner.txtファイルを追加してみましょう。このファイルをresourcesフォルダーに配置します。


 ${AnsiColor.BLUE} _ __ _ _ _ ___ | |_ ___ ___ / _` | | | |/ _ \| __/ _ \/ __| | (_| | |_| | (_) | || __/\__ \ \__, |\__,_|\___/ \__\___||___/ |_| ${AnsiColor.DEFAULT} :: Running Spring Boot ${AnsiColor.BLUE}${spring-boot.version}${AnsiColor.DEFAULT} :: Port #${AnsiColor.BLUE}${server.port}${AnsiColor.DEFAULT} ::


ここで、ローカルでサービスを開始すると、バナーが表示されます。


起動したら、 /swagger-docsエンドポイントにアクセスして、Swagger Docs が動作していることを検証できます。



最後に、将来の変更を追跡できるように、新しい Git ベースのリポジトリを作成します。


 $ git init $ git add . $ git commit -m "Initial commit for the Motivational Quotes API"


それでは、サービスをどれだけ早く展開できるか見てみましょう

Heroku を使って旅を終える

これまでのところ、私の新しいアイデアを導入するための主な焦点は、OpenAPI 仕様を作成し、サービス用のビジネス ロジックを記述することでした。Spring Boot が他のすべてを処理してくれました。


サービスを実行する場合、Spring Boot サービスに最適な Heroku を使用することを好みます。クラウド インフラストラクチャの問題に悩まされることなく、サービスを迅速に展開できます。また、Heroku を使用すると、Java ベースのアプリケーションの構成値を簡単に渡すことができます。


使用している Java バージョンに合わせて、プロジェクトのルート フォルダーにsystem.propertiesファイルを作成します。ファイルには次の 1 行が含まれます。


 java.runtime.version = 17


次に、デプロイメントの動作をカスタマイズするために、同じ場所にProcfileを作成します。このファイルにも次の 1 行があります。


 web: java -jar build/libs/quotes-0.0.1-SNAPSHOT.jar


いよいよデプロイです。Heroku CLIを使用すると、いくつかの簡単なコマンドでサービスをデプロイできます。まず、CLI を認証し、新しい Heroku アプリを作成します。


 $ heroku login $ heroku create Creating app... done, vast-crag-43256 https://vast-crag-43256-bb5e35ea87de.herokuapp.com/ | https://git.heroku.com/vast-crag-43256.git


私の Heroku アプリ インスタンスの名前はvast-crag-43256 (指定した名前を渡すこともできます) で、サービスは https://vast-crag-43256-bb5e35ea87de.herokuapp.com/ で実行されます。


最後に、Git コマンドを使用してコードを Heroku にプッシュし、サービスをデプロイします。


 $ git push heroku master


このコマンドが完了すると、Heroku ダッシュボードからデプロイメントの成功を検証できます。


これで、新しいサービスを試用する準備が整いました。

行動に活かすモチベーションの名言

Heroku で実行されている Motivational Quotes サービスでは、一連のcurlコマンドを使用してすべてが期待どおりに動作していることを検証できます。


まず、5 つのやる気を起こさせる名言の完全なリストを見てみましょう。


 $ curl \ --location 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes'


 [ { "id":1, "quote":"The greatest glory in living lies not in never falling, but in rising every time we fall." }, { "id":2, "quote":"The way to get started is to quit talking and begin doing." }, { "id":3, "quote":"Your time is limited, so don't waste it living someone else's life." }, { "id":4, "quote":"If life were predictable it would cease to be life, and be without flavor." }, { "id":5, "quote":"If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success." } ]


ID で 1 つのモチベーションを高める引用文を取得してみましょう。


 $ curl \ --location 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes/3'


 { "id":3, "quote":"Your time is limited, so don't waste it living someone else's life." }


ランダムにモチベーションを高める引用文を挙げてみましょう:


 $ curl --location \ 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes/random'


 { "id":5, "quote":"If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success." }


Swagger Docs も参照できます。


結論

市場投入までの時間は、どんなアイデアでも成功か失敗かを左右します。スタートアップ企業がイノベーションをできるだけ早く実現することに注力しているのはこのためです。ゴールに到達するまでの時間が長ければ長いほど、競合他社に先を越されるリスクが高まります。


読者の皆さんは、私の個人的なミッションステートメントを覚えているかもしれません。これは、あらゆる IT プロフェッショナルに当てはまると思います。


「知的財産の価値を高める機能や特徴を提供することに時間を集中してください。他のすべてについてはフレームワーク、製品、サービスを活用してください。」

— J. ベスター


この記事では、Spring Boot が RESTful API の実装に必要なすべての処理をどのように行うかを見てきました。ChatGPT を活用することで、私たちが望むサービスを人間の言葉で表現することもでき、数秒で OpenAPI 仕様が作成されました。これにより、API ファースト アプローチを活用できるようになりました。準備ができたら、いくつかの CLI コマンドを発行して Heroku を使用してアイデアを実現できました。

Spring Boot、ChatGPT、Heroku は、私が自分のアイデアを実現することに集中し続けるためのフレームワークとサービスを提供してくれました。その結果、私は自分のミッション ステートメントを忠実に守ることができ、さらに重要なことに、自分のアイデアを迅速に実現することができました。私がしなければならなかったのは、自分のアイデアの背後にあるビジネス ロジックに集中することだけでした。そして、それが本来あるべき姿です。


ご興味があれば、この記事のソースコードはGitLabでご覧いただけます。


本当に素晴らしい一日をお過ごしください!