왜 spring boot를 써야하는가?
-> Spring Boot는 “웹 서비스나 서버 프로그램을 훨씬 쉽게 만들게 해주는 도구”라서, 자바만으로 서버를 만들면 너무 귀찮고 복잡하니까 Spring Boot를 쓰는 것!
스프링부트는
- 서버를 쉽게 띄워줌
- REST API 만들기 쉬움
- DB 연결 쉽게 해줌
- 객체를 JSON으로 바꿔줌
- 설정 파일로 관리 가능
- 에러 처리 구조도 잘 잡혀 있음
그래서 개발자가 “게시글 저장”, “회원가입”, “조회” 같은 진짜 기능 구현에 더 집중할 수 있다.
- API, 왜 필요한가요?
API (Application Programming Interface) : 웹 서비스에서 데이터를 주고받기 위한 규칙
HTTP (hypertext transfer protocol) : 웹 브라우저와 서버가 하이퍼텍스트, 즉 웹 페이지의 내용을 주고받을 때 사용하는 규칙
- 비연결성(1회성 요청)
- 무상태성
- 클라이언트-서버 모델
- REST API
REST API (Reprsentational State Transfer) : 웹에서 데이터를 주고받기 위한 규칙
- 자원은 URL(ex. http://localhost:8080/api/posts)로 표현
- 행동은 HTTP메서드로 표현
- 자원에는 명사 사용, 동사 사용 안함
- 서버는 요청 결과에 따라 적절한 HTTP 상태코드 반환
구조 뜯어보기 (http://localhost:8080/api/posts)
- Protocol: http (통신 규약)
- Host (Domain): localhost (내 컴퓨터 주소)
- Port: 8080 (스프링 부트가 열어둔 문 번호)
- Path: /api/posts (서버 내부의 상세 경로 - 이게 바로 엔드포인트!)
Spring Boot에서 REST API를 많이 쓰는 이유는?
- HTTP랑 잘 맞음 : Spring Boot는 기본적으로 웹 서버 기반이고, REST는 HTTP 메서드를 그대로 잘 활용.
- 프론트엔드와 연결하기 쉬움 : React, Vue, Android, iOS 같은 클라이언트들은 보통 서버와 JSON 데이터로 통신함. REST API는 보통 JSON을 주고받으니까 프론트와 붙이기 편함.
- 서버와 클라이언트를 분리하기 좋음 : REST API는 화면을 서버가 직접 만들어 주는 방식이 아니라, 데이터만 제공하는 방식이라 역할 분리가 쉬움
- Spring Boot가 REST 개발을 매우 쉽게 지원함 : Spring Boot에서는 REST API를 거의 바로 만들 수 있다.
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
return "user " + id;
}
}
- Controller 실습
package com.example.springboot_twitter;
import com.example.springboot_twitter.repository.PostRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
@RequiredArgsConstructor //생성자 생성 역할
@RestController
public class PostController {
private final PostRepository postRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/api/posts") //글쓰기
public ResponseEntity<Post> createPost(@RequestBody Post post){
Post newPost = new Post(null, post.getContent(), LocalDateTime.now());
postRepository.save(newPost);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(newPost);
}
@GetMapping("/api/posts")
public List<Post> getAllPosts(){
return postRepository.findAll();
}
@GetMapping("/api/posts/{id}") //게시글 가져오기
public Post getPost(@PathVariable Long id){
return postRepository.findById(id).orElseThrow();
}
@PutMapping("/api/posts/{id}") //게시글 생성
public Post updatePost(@PathVariable Long id, @RequestBody Post postRequest){
return postRepository.findById(id).map(post->{
post.updateContent(postRequest.getContent());
return postRepository.save(post);
}).orElseThrow();
}
@DeleteMapping("/api/posts/{id}") //게시글 삭제
public void deletePost(@PathVariable Long id){
postRepository.deleteById(id);
}
// /api/posts/search?page=1&size=3
@GetMapping("/api/posts/search") //게시글 검색
public List<Post> getAllPosts(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "3") int size
){
return postRepository.findAllPaged(page,size);
}
}
Controller : 클라이언트의 요청을 받아서 처리하는 역할을 하는 클래스, Spring Boot에서는 @Controller 또는 @RestController 어노테이션을 사용하여 컨트롤러를 만들 수 있다
--> 어노테이션 (annotation) 은 무엇인가?
자바에서 “이 클래스나 메서드는 이런 역할이에요”라고 표시해주는 표식
컨트롤러에서 자주 쓰는 어노테이션들
- @Controller : 일반 컨트롤러
- @RestController : 데이터 반환용 컨트롤러
- @RequestMapping : 기본 URL 지정
- @GetMapping : 조회
- @PostMapping : 생성
- @PutMapping : 전체 수정
- @PatchMapping : 일부 수정
- @DeleteMapping : 삭제
- @PathVariable : URL 값 받기
- @RequestParam : 쿼리스트링 값 받기
- @RequestBody : 요청 본문의 JSON 받기
- Postman 으로 API 실습
Postman에 내가 만든 URL을 넣고, 거기에 맞는 HTTP 메서드(GET, POST 등) 를 설정해서 요청 보내면 됨!

나에게 가장 생소한 개념은 페이지네이션이었다.
페이지네이션 : 데이터를 한 번에 다 보여주지 않고, 여러 페이지로 나눠서 보여주는 것
.sorted((Post p1, Post p2) -> Long.compare(p2.getId(), p1.getId()))
p2를 앞에 두고 비교해서, id가 큰 값이 먼저 오게 만들었기 때문에 캡쳐본엔 0페이지에 큰 수부터 나오는 것.
- Spring Data JPA
JPA (Java Persistence API) : JPA는 자바 객체와 DB 테이블을 연결해서, SQL을 직접 다 많이 쓰지 않아도 DB 작업을 할 수 있게 해줌
Spring Data JPA : Spring 애플리케이션에서 데이터베이스를 쉽게 사용할 수 있도록 도와주는 라이브러리. JPA를 기반으로 하며, 반복적인 데이터베이스 접근 코드를 줄이고 객체 지향적인 방식으로 데이터를 처리 할 수 있게 해.
예를 들어 원래는
- EntityManager 써야 하고
- persist, find 같은 걸 직접 다뤄야 하고
- 조회 메서드도 구현해야 하는데
Spring Data JPA를 쓰면 인터페이스만 작성해도 기본 CRUD를 대부분 자동으로 제공
엔티티 (= DB 테이블과 연결되는 자바 클래스)
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String content;
}
Repository (= 엔티티를 DB에 저장하고 꺼내오는 역할 )
public interface PostRepository extends JpaRepository<Post, Long> {
}
postRepository.save(post);
postRepository.findAll();
postRepository.findById(1L);
postRepository.deleteById(1L);
바로 호출 가능
DTO (= 화면이나 API로 주고받기 위한 데이터 묶음)
public class PostResponseDto {
private Long id;
private String title;
}
DB 테이블에 직접 연결되는 게 아닌, 응답용 / 요청용 데이터 상자
정리
- Spring Data JPA는 DB 작업을 쉽게 해준다
- 그런데 뭘 대상으로 쉽게 하냐?
- 바로 엔티티
- 그 엔티티를 다루는 통로가 Repository
- 인메모리 저장소 H2 Database 연결하기
PostRepository
package com.example.springboot_twitter.repository;
import com.example.springboot_twitter.Post;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
public interface PostRepository {
Post save(Post post);
List<Post> findAll();
Optional<Post> findById(Long id);
void deleteById(Long id);
List<Post> findAllPaged(int page, int size);
}
InMemoryPostRepository
package com.example.springboot_twitter.repository;
import com.example.springboot_twitter.Post;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
@Repository
public class InMemoryPostRepository implements PostRepository
{
private final Map<Long,Post> posts = new HashMap<>(); //실제 DB 대신하는 임시저장소
private final AtomicLong idGenerator = new AtomicLong(1);//자동 번호표기계
@Override
public Post save(Post post) {
Long id = post.getId() == null ? idGenerator.getAndIncrement() : post.getId();
post.setId(id);
posts.put(id,post);
return post;
}
@Override
public List<Post> findAll() {
return new ArrayList<>(posts.values());
}
@Override
public Optional<Post> findById(Long id) {
return Optional.ofNullable(posts.get(id));
}
@Override
public void deleteById(Long id) {
posts.remove(id);
}
@Override
public List<Post> findAllPaged(int page, int size) {
return posts.values()
.stream()
.sorted((Post p1, Post p2)->Long.compare(p2.getId(), p1.getId()))
.skip((long) page*size)
.limit(size)
.toList();
}
}
- MySql database 설정하기
Spring Boot 프로젝트 설정하기
build.gradle 파일에 MySQL 의존성을 추가
dependencies {
// MySQL 드라이버
implementation("com.mysql:mysql-connector-j")
데이터베이스 연결 설정
application.properties 파일에 MySQL 연결 정보를 설정
spring:
datasource:
url: jdbc:mysql://localhost:3306/twitterdb
username: dev
password: dev123

'백엔드' 카테고리의 다른 글
| [Spring Boot] tave 스터디 3주차 개념 정리 (0) | 2026.04.04 |
|---|---|
| [Spring Boot] tave 스터디 2주차 개념 정리 (0) | 2026.03.29 |