diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index 4c8102f1c8..cd8703f7f3 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -111,6 +111,7 @@
spring-boot-3-url-matching
spring-boot-graalvm-docker
spring-boot-validations
+ spring-boot-openapi
diff --git a/spring-boot-modules/spring-boot-openapi/pom.xml b/spring-boot-modules/spring-boot-openapi/pom.xml
new file mode 100644
index 0000000000..6612a429f9
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/pom.xml
@@ -0,0 +1,77 @@
+
+
+ 4.0.0
+ spring-boot-openapi
+ spring-boot-openapi
+ jar
+ OpenAPI Generator module
+
+
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ javax.validation
+ validation-api
+
+
+ io.swagger.core.v3
+ swagger-annotations
+ ${swagger-annotations.version}
+
+
+
+
+
+
+ org.openapitools
+ openapi-generator-maven-plugin
+ ${openapi-generator.version}
+
+
+
+ generate
+
+
+ true
+ ${project.basedir}/src/main/resources/api/quotes.yaml
+ spring
+ ApiUtil.java
+
+ custom
+ false
+ true
+ com.baeldung.tutorials.openapi.quotes.api
+ com.baeldung.tutorials.openapi.quotes.api.model
+ source
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+ 7.3.0
+ 2.2.20
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/QuotesApplication.java b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/QuotesApplication.java
new file mode 100644
index 0000000000..6a7e5fce12
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/QuotesApplication.java
@@ -0,0 +1,14 @@
+package com.baeldung.tutorials.openapi.quotes;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.baeldung.tutorials.openapi.quotes.service.BrokerService;
+
+@SpringBootApplication
+public class QuotesApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(QuotesApplication.class, args);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/OrdersApiImpl.java b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/OrdersApiImpl.java
new file mode 100644
index 0000000000..991d765b97
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/OrdersApiImpl.java
@@ -0,0 +1,9 @@
+package com.baeldung.tutorials.openapi.quotes.controller;
+
+import org.springframework.stereotype.Component;
+
+import com.baeldung.tutorials.openapi.quotes.api.OrdersApiDelegate;
+
+@Component
+public class OrdersApiImpl implements OrdersApiDelegate {
+}
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/QuotesApiImpl.java b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/QuotesApiImpl.java
new file mode 100644
index 0000000000..40a583d960
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/controller/QuotesApiImpl.java
@@ -0,0 +1,42 @@
+package com.baeldung.tutorials.openapi.quotes.controller;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import com.baeldung.tutorials.openapi.quotes.api.QuotesApiDelegate;
+import com.baeldung.tutorials.openapi.quotes.api.model.QuoteResponse;
+import com.baeldung.tutorials.openapi.quotes.service.BrokerService;
+
+@Component
+public class QuotesApiImpl implements QuotesApiDelegate {
+ private final BrokerService broker;
+
+ public QuotesApiImpl(BrokerService broker) {
+ this.broker = broker;
+ }
+
+
+ /**
+ * GET /quotes/{symbol} : Get current quote for a security
+ *
+ * @param symbol Security's symbol (required)
+ * @return OK (status code 200)
+ * @see QuotesApi#getQuote
+ */
+ @Override
+ public ResponseEntity getQuote(String symbol) {
+
+ var price = broker.getSecurityPrice(symbol);
+
+ if ( price.isPresent()) {
+ var quote = new QuoteResponse();
+ quote.setSymbol(symbol);
+ quote.setPrice(price.get());
+ return ResponseEntity.ok(quote);
+ }
+ else {
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
+ }
+ }
+}
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/service/BrokerService.java b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/service/BrokerService.java
new file mode 100644
index 0000000000..f55c0a8656
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/java/com/baeldung/tutorials/openapi/quotes/service/BrokerService.java
@@ -0,0 +1,29 @@
+package com.baeldung.tutorials.openapi.quotes.service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Random;
+
+import org.springframework.lang.NonNull;
+import org.springframework.stereotype.Service;
+
+@Service
+public class BrokerService {
+
+ private Map securities = new HashMap<>();
+
+ public BrokerService() {
+ Random rnd = new Random();
+ securities.put("GOOG", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
+ securities.put("AA", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
+ securities.put("BAEL", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
+ }
+
+
+ public Optional getSecurityPrice(@NonNull String symbol) {
+ return Optional.ofNullable(securities.get(symbol));
+ }
+}
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/resources/api/quotes.yaml b/spring-boot-modules/spring-boot-openapi/src/main/resources/api/quotes.yaml
new file mode 100644
index 0000000000..283395e27a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/resources/api/quotes.yaml
@@ -0,0 +1,130 @@
+openapi: 3.0.0
+info:
+ title: Quotes API
+ version: 1.0.0
+servers:
+ - description: Test server
+ url: http://localhost:8080
+paths:
+ /quotes/{symbol}:
+ get:
+ tags:
+ - quotes
+ summary: Get current quote for a security
+ operationId: getQuote
+ security:
+ - ApiKey:
+ - Quotes.Read
+ parameters:
+ - name: symbol
+ in: path
+ required: true
+ description: Security's symbol
+ schema:
+ type: string
+ pattern: '[A-Z0-9]+'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QuoteResponse'
+ /orders/{symbol}:
+ post:
+ tags:
+ - orders
+ operationId: createOrder
+ security:
+ - ApiKey:
+ - Orders.Write
+ summary: Places a new order to buy a security
+ parameters:
+ - name: symbol
+ in: path
+ required: true
+ description: Security's symbol
+ schema:
+ type: string
+ pattern: '[A-Z0-9]'
+ requestBody:
+ required: true
+ description: Order info
+ content:
+ 'application/json':
+ schema:
+ $ref: '#'#/components/schemas/OrderRequest'
+ responses:
+ '201':
+ description: Order accepted
+ content:
+ 'application/json':
+ schema:
+ $ref: '#/components/schemas/OrderResponse'
+
+components:
+ securitySchemes:
+ ApiKey:
+ type: apiKey
+ in: header
+ name: X-API-KEY
+
+ schemas:
+ OrderType:
+ type: string
+ enum:
+ - BUY
+ - SELL
+ OrderStatus:
+ type: string
+ enum:
+ - PENDING
+ - REJECTED
+ - FULFILLED
+ QuoteResponse:
+ description: Quote response
+ type: object
+ properties:
+ symbol:
+ type: string
+ description: security's symbol
+ price:
+ type: number
+ description: Quote value
+ OrderRequest:
+ description: Buy/Sell order details
+ type: object
+ properties:
+ clientRef:
+ type: string
+ orderType:
+ $ref: '#/components/schemas/OrderType'
+ symbol:
+ type: string
+ description: security's symbol
+ quantity:
+ type: number
+ price:
+ type: number
+ OrderResponse:
+ description: Buy/Sell order response
+ properties:
+ clientRef:
+ type: string
+ orderType:
+ $ref: '#/components/schemas/OrderType'
+ symbol:
+ type: string
+ description: security's symbol
+ quantity:
+ type: number
+ price:
+ type: number
+ orderStatus:
+ $ref: '#/components/schemas/OrderStatus'
+
+
+
+
+
+
diff --git a/spring-boot-modules/spring-boot-openapi/src/main/resources/application.yaml b/spring-boot-modules/spring-boot-openapi/src/main/resources/application.yaml
new file mode 100644
index 0000000000..7f074c3a3b
--- /dev/null
+++ b/spring-boot-modules/spring-boot-openapi/src/main/resources/application.yaml
@@ -0,0 +1,4 @@
+logging:
+ level:
+ root: INFO
+ org.springframework: DEBUG
\ No newline at end of file