BACKEND/스프링 Spring Boot

Spring BOOT 를 사용해서 JPA, H2를 이용한 간단한 API 작성

꾸준히개발하자 2024. 1. 9. 13:06

먼저 스프링 과 스프링 부트의 차이점 

부트는 톰켓을 내장하고 있고 설정을 편리하게 할수있다는 점이 가장 큰 메리트 인것 같다 

 

API 란 ?
Application Programming Interface 의 줄임말
응용프로그램에서 사용할 수 있도록
다른 응용프로그램을 제어할 수 있게 만든 인터페이스
API를 사용하면 내부 구현 로직을 알지못해도 정의되어 있는
기능을 쉽게 사용할 수 있음

여기서 인터페이스란 어떤 장치간 정보를 교환하기 위한 수단이나 방법을 의미
대표적인 인터페이스 예로는 마우스 , 키보드 , 터치패드 등이 있음

REST API
- 자원의 이름으로 구분하여 해당 자원의 상태를 교환
REST 는 서버와 클라이언트의 통신 방식 중 하나임
HTTP URI 를 통해 자원을 명시하고 HTTP Method 를 통해 자원을 교환

HTTP method : Create , Read , Update , Delete 

Server - Client
자원이 있는 쪽이 Server , 요청하는 쪽이 Client
클라이언트와 서버가 독립적으로 분리되어 있어야 함 

Stateless
요청간에 클라이언트 정보가 서버에 저장되지 않음
서버는 각각의 요청을 완전히 별개의 것으로 인식하고 처리

Cacheable 
HTTP 프로토콜을 그대로 사용하기 때문에 HTTP 의 특징인
캐싱 기능을 적용 대량의 요청을 효율적으로 처리하기 위해 캐시 사용

 

 

 

 

커뮤니티 버전은 이니셜라이저가 없으므로 

https://start.spring.io/  에서 스프링부트를 만들었다 

 

 

 

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.7</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>one-hour-project</groupId>
	<artifactId>one-hour-project</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>one-hour-project</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

 

버전을 3.2.1 에서 실행시 오류가 발생해서  2.7.7 로 바꾸었더니 오류가 없어졌다

 

 

 

메이븐 방식 pom.xml 에

data JPA , H2 데이터베이스 ,   라이브러리를 추가 해서 의존성 주입 하였다 

 

 

설정 창 Enable annotation 를 체크해서 롬복 을 사용할수 있도록 한다.  

 

 

프로젝트 구성도

 

 

MemberController

 

package onehourproject.onehourproject.Member.controller;

import lombok.RequiredArgsConstructor;
import onehourproject.onehourproject.Member.controller.dto.JoinRequest;
import onehourproject.onehourproject.Member.service.MemberService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    // 자원을 가져옴
    @GetMapping("/hello")
    public String getHello(){
        return "hello Around Web Studio";
    }

    // 자원을 넣어줌
    @PostMapping("/join")
    public String postHello(@RequestBody JoinRequest joinRequest){  // RequestBody 를 받기 위해서 DTO 가 필요

        String id = joinRequest.getId();
        String name = joinRequest.getName();
        String phoneNumber = joinRequest.getPhoneNumber();

        String result = memberService.join(id,name,phoneNumber);

        if(result.equalsIgnoreCase("success")) {
            return "success";
        } else {
            return "fail";
        }
    }
}

 

 

 

/hello 요청 시  

문자열 반환 

 

 

H2 데이터베이스를 사용하였다

H2 데이터 베이스 설치 게시물을 참조 

bin . h2.bat 배치파일 실행 

 

application.properties  h2 설정 추가

# H2 설정
spring.h2.console.enabled=true
spring.h2.console.path=/h2

# Datasource 설정
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=

 

 

 

 

 

 

 

 

 

 

테스트 코드 작성 

MemberRepositoryTest

package onehourproject.onehourproject.memberrepository;

import onehourproject.onehourproject.Member.repository.MemberRepository;
import onehourproject.onehourproject.Member.repository.entity.Member;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Repository;

@SpringBootTest
public class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    public void crudTesT(){
        Member member = Member.builder()
                .id("flature")
                .name("플래처")
                .phoneNumber("010-0000-0000")
                .build();

        // create test
        memberRepository.save(member);

    }
}

 

 

테스트 성공

 

 

 

MemberRepository

package onehourproject.onehourproject.Member.repository;

import onehourproject.onehourproject.Member.repository.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member,Long> {
    // JPA 메서드들을 사용할수 있다.
}

 

JPA 기능들을 사용하기 위해 JpaRepository 를 상속받는다 Member 엔티티 와 Long 타입 지정 

 

 

 

Member 엔티티 

package onehourproject.onehourproject.Member.repository.entity;

import lombok.*;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Getter
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long index;

    private String id;

    private String name;

    private String phoneNumber;

}

 

  1. @Entity:
    • @Entity 어노테이션은 클래스가 JPA의 엔티티임을 나타냅니다. 이는 해당 클래스가 데이터베이스 테이블의 구조를 나타내는 데 사용될 수 있음을 의미합니다.
    • @Entity가 적용된 클래스는 보통 데이터베이스의 테이블에 매핑되며, 이 클래스의 인스턴스는 테이블의 레코드(행)에 해당합니다.
    • 이 어노테이션을 사용하면 JPA 프로바이더(예: Hibernate)가 클래스를 데이터베이스 테이블에 매핑하고, 객체의 생명주기를 관리할 수 있습니다.
  2. @Builder:
    • @Builder는 디자인 패턴 중 하나인 빌더 패턴을 구현하는 데 사용됩니다. 이 어노테이션은 주로 Lombok 라이브러리에서 제공됩니다.
    • 빌더 패턴은 복잡한 객체를 단계적으로 구축할 수 있게 해주며, 결과적으로 가독성이 좋고 오류가 적은 코드를 작성할 수 있도록 돕습니다.
    • @Builder를 사용하면 객체의 생성자나 정적 팩토리 메소드 대신, 읽기 쉽고 유연한 방식으로 객체를 생성할 수 있습니다.
    • 이는 특히 많은 필드를 가진 객체를 생성할 때 유용하며, 필드에 대한 설정을 체인 방식으로 연결하여 코드를 더 명확하게 만들 수 있습니다.

 

 

 

MemberService

 

package onehourproject.onehourproject.Member.service;

public interface MemberService {

    String join(String id , String name , String phoneNumber);

}

 

 

MemberServiceImpl

package onehourproject.onehourproject.Member.service;


import lombok.RequiredArgsConstructor;
import onehourproject.onehourproject.Member.repository.MemberRepository;
import onehourproject.onehourproject.Member.repository.entity.Member;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    @Override
    public String join(String id, String name, String phoneNumber) {
        Member member = Member.builder()
                .id(id)
                .name(name)
                .phoneNumber(phoneNumber)
                .build();
        memberRepository.save(member);

        return "success";
    }
}

join 메서드 가입 완료시 success 반환 

 

 

MemberController

 

package onehourproject.onehourproject.Member.controller;

import lombok.RequiredArgsConstructor;
import onehourproject.onehourproject.Member.controller.dto.JoinRequest;
import onehourproject.onehourproject.Member.service.MemberService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    // 자원을 가져옴
    @GetMapping("/hello")
    public String getHello(){
        return "hello Around Web Studio";
    }

    // 자원을 넣어줌
    @PostMapping("/join")
    public String postHello(@RequestBody JoinRequest joinRequest){  // RequestBody 를 받기 위해서 DTO 가 필요

        String id = joinRequest.getId();
        String name = joinRequest.getName();
        String phoneNumber = joinRequest.getPhoneNumber();

        String result = memberService.join(id,name,phoneNumber);

        if(result.equalsIgnoreCase("success")) {
            return "success";
        } else {
            return "fail";
        }
    }
}

 

RequestBody 를 받기 위해서 DTO 가 필요하다

DTO의 JoinRequest 객체를 사용하여 아이디 , 이름 폰넘버를 가져온다

가져온 정보로 memberService 를 실행해서 

result 결과 값에 따라서 success , fail 문자열을 반환한다.  

 

JoinRequest

package onehourproject.onehourproject.Member.controller.dto;

import lombok.Data;

@Data

public class JoinRequest {

    private String id;
    private String name;
    private String phoneNumber;
}

 

 

POST 방식으로 Body 에 담아서 보내기 위해 Talend API Tester 를 사용했다

 

사용 방법 설치 는 이곳을 참고 했다

https://mainia.tistory.com/6168

 

크롬 웹 API 테스트툴 확장 프로그램 Talend API Tester 사용법

얼마전 크롬 확장 프로그램으로 많이 사용하던 API 테스트툴 Postman이 서비스를 중단했습니다. 이유는 알 수 없지만 윈도우 PC 에 설치한 앱으로 테스트를 해야 합니다. 그래서 다른 웹 API 툴이 없

mainia.tistory.com

 

 

성공적으로 요청을 받았다 200

 

 

 

 

다시 H2 데이터베이스에 접속 한다 

설정한 URL 로 접속해야 한다.

 

 

 

DB에 값이 추가된것을 알수있다.