Skip to content

Commit

Permalink
Created openapi.yml and added plugin (#48)
Browse files Browse the repository at this point in the history
- Created openapi.yml and added maven plugin
  • Loading branch information
LauroSilveira authored Jun 26, 2024
1 parent f41d458 commit 2e30df7
Show file tree
Hide file tree
Showing 36 changed files with 597 additions and 284 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'
cache: maven

Expand All @@ -32,10 +32,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'
cache: maven

Expand Down
74 changes: 65 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

Expand All @@ -14,11 +14,16 @@
<version>0.0.1-SNAPSHOT</version>
<name>spring-reactive-api</name>

<description>Demo project for Spring Boot</description>
<description>Spring boot API with React</description>

<properties>
<java.version>17</java.version>
<java.version>21</java.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<package.name>com.lauro.correia.reactive</package.name>
<openapi.generator.version>7.5.0</openapi.generator.version>
<swagger-annotations.version>2.2.22</swagger-annotations.version>
<swagger-models.version>2.2.22</swagger-models.version>
<jackson-databind-nullable.version>0.2.6</jackson-databind-nullable.version>
</properties>

<dependencies>
Expand All @@ -36,23 +41,37 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.5.0</version>
</dependency>
<!-- MapStruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!-- Swagger / OpenApi -->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger-models.version}</version>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>${jackson-databind-nullable.version}</version>
</dependency>

<!-- Spring Starters Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -83,7 +102,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
Expand Down Expand Up @@ -126,6 +144,44 @@
</execution>
</executions>
</plugin>

<!-- OpenApi Maven generator -->
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi.generator.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/spec/openapi.yaml</inputSpec>
<generatorName>spring</generatorName>
<modelNameSuffix>Dto</modelNameSuffix>
<apiPackage>${package.name}.api</apiPackage>
<modelPackage>${package.name}.model</modelPackage>
<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
<generateModelDocumentation>false</generateModelDocumentation>
<generateApiDocumentation>false</generateApiDocumentation>
<configOptions>
<basePackage>${package.name}</basePackage>
<useSpringBoot3>true</useSpringBoot3>
<delegatePattern>true</delegatePattern>
<reactive>true</reactive>
<useResponseEntity>false</useResponseEntity>
<java8>true</java8>
<additionalModelTypeAnnotations>
@lombok.Data;
@lombok.NoArgsConstructor;
@lombok.AllArgsConstructor;
@lombok.Builder;
</additionalModelTypeAnnotations>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
package com.lauro.correia.reactive.api.controller;


import com.lauro.correia.reactive.api.PostApiDelegate;
import com.lauro.correia.reactive.api.service.post.PostService;
import com.lauro.correia.reactive.api.vo.CommentsVO;
import com.lauro.correia.reactive.model.CommentDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;


@Slf4j
@RestController
@RequestMapping("/post")
public class PostController {
public class PostController implements PostApiDelegate {

private final PostService postService;

public PostController(PostService postService) {
this.postService = postService;
}

@GetMapping(value = "/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<CommentsVO> getPostsCommentsByUser(@PathVariable("userId") final String userId) {
log.info("[UserInfoController] getUsers");
@Override
public Flux<CommentDto> getPostsCommentsByUser(String userId, ServerWebExchange exchange) {
log.info("[UserInfoController] Get posts comments by user {}", userId);
return this.postService.getPostCommentsByUser(userId);
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
package com.lauro.correia.reactive.api.controller;


import com.lauro.correia.reactive.api.UserApiDelegate;
import com.lauro.correia.reactive.api.service.user.UserService;
import com.lauro.correia.reactive.api.vo.UserInfoVO;
import com.lauro.correia.reactive.api.vo.UserVO;
import com.lauro.correia.reactive.model.UserDto;
import com.lauro.correia.reactive.model.UserInfoDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/user")
@Slf4j
@RequiredArgsConstructor
public class UserInfoController {
public class UserInfoController implements UserApiDelegate {

private final UserService userService;

@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<UserInfoVO> getUserInfo(@PathVariable("id") String id) {
@Override
public Flux<UserInfoDto> getUserInfo(String id, ServerWebExchange exchange) {
log.info("[UserInfoController] getUserInfo for Id: [{}]", id);
return this.userService.getUserInfoComplete(id);
}

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<UserVO> getUsers() {
@Override
public Flux<UserDto> getUsers(ServerWebExchange exchange) {
log.info("[UserInfoController] getUsers");
return this.userService.getUsers();
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.lauro.correia.reactive.api.controller;

import com.lauro.correia.reactive.api.exception.CustomMessageApiError;
import com.lauro.correia.reactive.api.exception.ServerErrorException;
import com.lauro.correia.reactive.api.exception.album.AlbumNotFoundException;
import com.lauro.correia.reactive.api.exception.post.PostNotFoundException;
import com.lauro.correia.reactive.api.exception.user.UserNotFoundException;
import com.lauro.correia.reactive.model.CustomMessageApiErrorDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -13,24 +13,24 @@
import reactor.core.publisher.Mono;

@Slf4j
@RestControllerAdvice(assignableTypes = UserInfoController.class)
@RestControllerAdvice
public class UserInfoRestControllerAdvice {

@ExceptionHandler({AlbumNotFoundException.class, PostNotFoundException.class, UserNotFoundException.class})
public Mono<ResponseEntity<CustomMessageApiError>> handleNotFoundException(final UserNotFoundException e) {
public Mono<ResponseEntity<CustomMessageApiErrorDto>> handleNotFoundException(final UserNotFoundException e) {
log.error("[UserInfoRestControllerAdvice] handleNotFoundException");
return Mono.just(ResponseEntity.status(HttpStatus.NOT_FOUND).body(CustomMessageApiError.builder()
.httpStatus(HttpStatus.NOT_FOUND)
return Mono.just(ResponseEntity.status(HttpStatus.NOT_FOUND).body(CustomMessageApiErrorDto.builder()
.httpStatus(HttpStatus.NOT_FOUND.value())
.msg(e.getMessage())
.build()));
}


@ExceptionHandler({ServerErrorException.class})
public Mono<ResponseEntity<CustomMessageApiError>> handleInternalServerException(final ServerErrorException ex) {
public Mono<ResponseEntity<CustomMessageApiErrorDto>> handleInternalServerException(final ServerErrorException ex) {
log.error("[UserInfoRestControllerAdvice] handleInternalServerException");
return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(CustomMessageApiError.builder()
.httpStatus(HttpStatus.INTERNAL_SERVER_ERROR)
return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(CustomMessageApiErrorDto.builder()
.httpStatus(HttpStatus.INTERNAL_SERVER_ERROR.value())
.msg(ex.getMessage())
.build()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
@Builder
public class CustomMessageApiError {

private HttpStatus httpStatus;
private int httpStatus;
private String msg;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.lauro.correia.reactive.api.exception;

import com.lauro.correia.reactive.model.CustomMessageApiErrorDto;
import lombok.Getter;

@Getter
public class ServerErrorException extends RuntimeException {

private final CustomMessageApiError customMessageApiError;
public ServerErrorException(String message, CustomMessageApiError customMessageApiError) {
private final CustomMessageApiErrorDto customMessageApiError;

public ServerErrorException(String message, CustomMessageApiErrorDto customMessageApiError) {
super(message);
this.customMessageApiError = customMessageApiError;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.lauro.correia.reactive.api.exception.user;

import com.lauro.correia.reactive.api.exception.CustomMessageApiError;
import com.lauro.correia.reactive.model.CustomMessageApiErrorDto;
import lombok.Getter;

@Getter
public class UserNotFoundException extends RuntimeException {

private final CustomMessageApiError customMessageApiError;
public UserNotFoundException(String message, CustomMessageApiError customMessageApiError) {
private final CustomMessageApiErrorDto customMessageApiError;
public UserNotFoundException(String message, CustomMessageApiErrorDto customMessageApiError) {
super(message);
this.customMessageApiError = customMessageApiError;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "spring", uses = {GeolocationMapper.class}, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
@Mapper(componentModel = "spring", uses = {GeolocationMapper.class})
public interface AddressMapper {

@Mapping(source = "geo", target = "geolocation")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.lauro.correia.reactive.api.mapper;

import com.lauro.correia.reactive.api.model.Album;
import com.lauro.correia.reactive.api.vo.AlbumVO;
import com.lauro.correia.reactive.model.AlbumDto;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import java.util.List;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
@Mapper(componentModel = "spring")
public interface AlbumMapper {

List<AlbumVO> mapToAlbumVO(List<Album> album);
List<AlbumDto> mapToAlbumDto(List<Album> album);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.lauro.correia.reactive.api.mapper;

import com.lauro.correia.reactive.api.model.Company;
import com.lauro.correia.reactive.api.vo.CompanyVO;
import org.mapstruct.InjectionStrategy;
import com.lauro.correia.reactive.model.CompanyDto;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
@Mapper(componentModel = "spring")
public interface CompanyMapper {
CompanyVO maptoCompanyVO(Company company);
CompanyDto maptoCompanyDto(Company company);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.lauro.correia.reactive.api.mapper;

import com.lauro.correia.reactive.api.model.Comments;
import com.lauro.correia.reactive.api.vo.CommentsVO;
import com.lauro.correia.reactive.model.CommentDto;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface PostCommentsMapper {
CommentsVO mapToCommentVO(Comments response);
CommentDto mapToCommentDto(Comments response);

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.lauro.correia.reactive.api.mapper;

import com.lauro.correia.reactive.api.model.Post;
import com.lauro.correia.reactive.api.vo.PostVO;
import com.lauro.correia.reactive.model.PostDto;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import java.util.List;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
@Mapper(componentModel = "spring")
public interface PostMapper {

List<PostVO> maptToVo(List<Post> post);
List<PostDto> mapToPostDto(List<Post> post);
}
Loading

0 comments on commit 2e30df7

Please sign in to comment.