Search

Board App - BackEnd (SpringBoot)

Board App REST API ์„œ๋ฒ„ ๊ตฌํ˜„

1.
Board ํ…Œ์ด๋ธ” ์ •์˜
2.
Spring Boot REST API ๊ตฌํ˜„
3.
API ๋ช…์„ธ์„œ ์ž๋™ ์ƒ์„ฑ - OpenAPI(Swagger)
4.
API ํ…Œ์ŠคํŠธ

Board ํ…Œ์ด๋ธ” ์ •์˜

boards.sql

DROP TABLE IF EXISTS `boards`; CREATE TABLE `boards` ( `no` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'PK', `id` VARCHAR(64) NOT NULL COMMENT 'UK', `title` VARCHAR(100) NOT NULL COMMENT '์ œ๋ชฉ', `writer` VARCHAR(100) NOT NULL COMMENT '์ž‘์„ฑ์ž', `content` TEXT NULL COMMENT '๋‚ด์šฉ', `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '๋“ฑ๋ก์ผ์ž', `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '์ˆ˜์ •์ผ์ž' ) COMMENT '๊ฒŒ์‹œํŒ';
SQL
๋ณต์‚ฌ

Spring Boot REST API ๊ตฌํ˜„

์š”์ฒญ ๋ฉ”์†Œ๋“œ
์š”์ฒญ ๊ฒฝ๋กœ
ํ•ญ๋ชฉ
Response
๋น„๊ณ 
GET
/boards
๊ฒŒ์‹œํŒ ๋ชฉ๋ก
{ โ€œlistโ€ : [], โ€œpaginationโ€ : }
GET
/boards?page=&size=
๊ฒŒ์‹œํŒ ๋ชฉ๋ก ํŽ˜์ด์ง•
{ โ€œlistโ€ : [], โ€œpaginationโ€ : }
GET
/boards/{id}
๊ฒŒ์‹œํŒ ์กฐํšŒ
{ }
POST
/boards
๊ฒŒ์‹œํŒ ๋“ฑ๋ก
โ€œSUCCESSโ€ 201 โ€FAILโ€ 400
PUT
/boards
๊ฒŒ์‹œํŒ ์ˆ˜์ •
โ€œSUCCESSโ€ 200 โ€FAILโ€ 400
DELETE
/boards/{id}
๊ฒŒ์‹œํŒ ์‚ญ์ œ
โ€œSUCCESSโ€ 200 โ€FAILโ€ 400
โ€ข
application.properties
โ€ข
domain
โ—ฆ
Boards.java
โ€ข
Mapper
โ—ฆ
BoardMapper.xml
โ—ฆ
BaseMapper.java
โ—ฆ
BoardMapper.java
โ€ข
Service
โ—ฆ
BaseService.java
โ—ฆ
boardservice.java
โ—ฆ
boardserviceImpl.java
โ€ข
Controller
โ—ฆ
BoardController.java
โ—ฆ
@CrossOrigin("*")
โ—ฆ
@RestController
โ–ช
sp-crud

application.properties

# ๋ฐ์ดํ„ฐ ์†Œ์Šค - MySQL spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aloha?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true spring.datasource.username=aloha spring.datasource.password=123456 # Mybatis ์„ค์ • mybatis.configuration.map-underscore-to-camel-case=true mybatis.type-aliases-package=com.aloha.boards.domain mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Java
๋ณต์‚ฌ

API ๋ช…์„ธ์„œ ์ž๋™ ์ƒ์„ฑ - OpenAPI(Swagger)

// Springdoc openapi implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
SQL
๋ณต์‚ฌ

build.gradle

plugins { id 'java' id 'war' id 'org.springframework.boot' version '3.4.1' id 'io.spring.dependency-management' version '1.1.6' } group = 'com.aloha' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.4' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.4' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // Springdoc openapi implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0' } tasks.named('test') { useJUnitPlatform() }
SQL
๋ณต์‚ฌ

SwaggerConfig.java

import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; @Configuration public class SwaggerConfig { @Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("aloha") // ๊ทธ๋ฃน๋ช… ์„ค์ • .pathsToMatch("/**") // ๊ฒฝ๋กœ ์„ค์ • .build(); } @Bean public OpenAPI springShopOpenAPI() { return new OpenAPI() .info(new Info().title("๊ฒŒ์‹œํŒ Proejct API") .description("๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ API ์ž…๋‹ˆ๋‹ค.") .version("v0.0.1")); } }
Java
๋ณต์‚ฌ

๊ธฐ๋ณธ ๊ฒฝ๋กœ

PageHelper ๋ฅผ ์ด์šฉํ•œ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ

builde.gradle

// pagehelper implementation 'com.github.pagehelper:pagehelper-spring-boot-starter:2.1.0'
Java
๋ณต์‚ฌ

application.properites

# PageHelper ์„ค์ • pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql
Java
๋ณต์‚ฌ

Pagination.java

import lombok.Data; /** * [ํŽ˜์ด์ง•] * โœ… ํŽ˜์ด์ง€ ํ•„์ˆ˜ ์ •๋ณด * - ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ : page * - ํŽ˜์ด์ง€๋‹น ๊ฒŒ์‹œ๊ธ€ ์ˆ˜ : size * - ๋…ธ์ถœ ํŽ˜์ด์ง€ ๊ฐœ์ˆ˜ : count * - ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ : total * * โญ ํŽ˜์ด์ง€ ์ˆ˜์‹ ์ •๋ณด * - ์‹œ์ž‘ ๋ฒˆํ˜ธ : start * - ๋ ๋ฒˆํ˜ธ : end * - ์ฒซ ๋ฒˆํ˜ธ : first * - ๋งˆ์ง€๋ง‰ ๋ฒˆํ˜ธ : last * - ์ด์ „ ๋ฒˆํ˜ธ : prev * - ๋‹ค์Œ ๋ฒˆํ˜ธ : next * - ๋ฐ์ดํ„ฐ ์ˆœ์„œ ๋ฒˆํ˜ธ : index */ @Data public class Pagination { // ํŽ˜์ด์ง• ๊ธฐ๋ณธ๊ฐ’ private static final long PAGE_NUM = 1; // ํ˜„์žฌ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ๊ธฐ๋ณธ๊ฐ’ private static final long SIZES = 10; // ํŽ˜์ด์ง€๋‹น ๊ฒŒ์‹œ๊ธ€ ์ˆ˜ ๊ธฐ๋ณธ๊ฐ’ private static final long COUNT = 10; // ๋…ธ์ถœ ํŽ˜์ด์ง€ ๊ฐœ์ˆ˜ ๊ธฐ๋ณธ๊ฐ’ // โœ… ํ•„์ˆ˜ ์ •๋ณด private long page; private long size; private long count; private long total; // โญ ์ˆ˜์‹ ์ •๋ณด private long start; private long end; private long first; private long last; private long prev; private long next; private long index; // ์ƒ์„ฑ์ž public Pagination() { this(0); } // ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ public Pagination(long total) { this(PAGE_NUM, total); } // ํ˜„์žฌ ๋ฒˆํ˜ธ, ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ public Pagination(long page, long total) { this(page, SIZES, COUNT, total); } // ํ•„์ˆ˜ ์ •๋ณด public Pagination(long page, long size, long count, long total) { this.page = page; this.size = size; this.count = count; this.total = total; calc(); } // setter // * ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ ์ง€์ • ํ›„, ํŽ˜์ด์ง€ ์ˆ˜์‹ ์žฌ๊ณ„์‚ฐ public void setTotal(long total) { this.total = total; calc(); } // ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ์ˆ˜์‹ public void calc() { // ์ฒซ ๋ฒˆํ˜ธ this.first = 1; // ๋งˆ์ง€๋ง‰ ๋ฒˆํ˜ธ this.last = (this.total - 1) / size + 1; // ์‹œ์ž‘ ๋ฒˆํ˜ธ this.start = ( (page-1) / count ) * count + 1; // ๋ ๋ฒˆํ˜ธ this.end = ( (page-1) / count + 1 ) * count; if( this.end > this.last ) this.end = this.last; // ์ด์ „ ๋ฒˆํ˜ธ this.prev = this.page - 1; // ๋‹ค์Œ ๋ฒˆํ˜ธ this.next = this.page + 1; // ๋ฐ์ดํ„ฐ ์ˆœ์„œ ๋ฒˆํ˜ธ this.index = (this.page - 1) * this.size; } }
Java
๋ณต์‚ฌ