11월 9일

Yullgiii·2023년 11월 9일
0
post-thumbnail

RestTemplate에 대해 알아보자! 🔍

🌐 RestTemplate란?

스프링 프레임워크에 내장된 RestTemplate은 RESTful 서비스를 소비하기 위한 동기식 HTTP 클라이언트다. 웹 서비스와의 통신을 추상화하여 HTTP 요청을 Java 객체로 매핑하고, 웹 서비스 결과를 다시 객체로 변환하는 역할을 한다.

📡 RestTemplate의 주요 메서드

  1. getForObject() 메서드

REST API를 호출해 결과 데이터를 Java 객체로 직접 받아야 할 때 사용.
이 메서드는 URL, 반환될 객체 타입, URI 변수들을 인자로 받는다.
예시 코드:

String resourceUrl = 'http://api.example.com/users/1';
User user = restTemplate.getForObject(resourceUrl, User.class);
System.out.println(user.getName());

위 코드는 'http://api.example.com/users/1'의 주소로부터 사용자 정보를 받아와서 User 클래스의 객체로 변환합니다.

  1. getForEntity() 메서드

getForObject()와 비슷하지만, 반환값으로 ResponseEntity<T> 객체를 받는다. 이 객체를 통해 HTTP 응답의 헤더, 상태 코드, 본문 등을 접근할 수 있다.
이 메서드는 요청을 보낸 후, 응답에 대한 더 많은 정보가 필요할 때 유용.
예시 코드:

ResponseEntity<User> response = restTemplate.getForEntity(resourceUrl, User.class);
if(response.getStatusCode() == HttpStatus.OK) {
  User user = response.getBody();
  System.out.println(user.getName());
}
  1. postForObject(), postForEntity() 메서드

서버에 데이터를 전송하고, 결과로 새롭게 생성된 리소스의 정보를 받을 때 사용. postForObject()는 결과 데이터를 바로 객체로 반환하지만, postForEntity()ResponseEntity<T>를 통해 응답 전체를 받는다.
이 메서드는 객체를 JSON으로 변환하여 HTTP POST 요청 본문에 넣고, 결과를 객체로 받는다.
예시 코드:

User newUser = new User("newuser", "password");
URI location = restTemplate.postForLocation(url, newUser);
User user = restTemplate.postForObject(url, newUser, User.class);
ResponseEntity<User> response = restTemplate.postForEntity(url, newUser, User.class);
  1. exchange() 메서드

용도: 다양한 HTTP 메서드를 실행하고, 상세한 요청 정보를 설정할 때 사용.
이 메서드는 HttpEntity 객체를 사용하여 요청 헤더와 본문을 설정할 수 있고, ParameterizedTypeReference<T>를 사용하여 반환 타입을 지정할 수 있다.
예시 코드:

HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);

ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
System.out.println(response.getBody());

위 코드는 주어진 URL로부터 JSON 응답을 String 타입으로 받아 출력.

RestTemplate 사용 예제

// GET 요청
ResponseEntity<User> response = restTemplate.getForEntity(url + "/1", User.class);
System.out.println("사용자 이름: " + response.getBody().getName());

// POST 요청
User newUser = new User("newuser", "password123");
URI location = restTemplate.postForLocation(url, newUser);
System.out.println("생성된 사용자의 URI: " + location.toString());

Entity 관계 이해하기 🤝

🔄 Entity의 관계

데이터베이스에서의 'Entity'는 테이블을 의미하며, 'Entity 관계'는 테이블 간의 관계를 말한다. 이 관계는 데이터의 일관성과 무결성을 유지하는 데 필수적이다.

주요 Entity 관계 유형
1:1 (일대일): 한 엔티티가 다른 하나의 엔티티와만 관계를 가지는 경우다. 예를 들어, 한 사람은 하나의 여권 번호를 가진다.
N:1 (다대일): 여러 엔티티가 단일 엔티티와 관계를 맺는 경우다. 예를 들어, 여러 개의 주문이 하나의 고객에게 연결될 수 있다.
1:N (일대다): 하나의 엔티티가 여러 개의 엔티티와 관계를 맺는 경우다. 예를 들어, 한 강의에 여러 학생이 등록될 수 있다.
Entity 관계 설정 예제

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "user")
    private List<Order> orders;
    // ... 기타 필드, 생성자, 게터, 세터
}

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    // ... 기타 필드, 생성자, 게터, 세터
}

이 예제에서User엔티티는 Order 엔티티와 1:N 관계를 가지고 있다. 하나의 User는 여러 Order를 가질 수 있고, Order는 하나의 User에 속한다.이 관계들을 올바르게 설정하고 구현하는 것은 데이터의 일관성을 유지하고, 쿼리의 효율성을 높이며, 애플리케이션의 확장성을 보장하는 데 중요하다.

N:M (다대다) 관계에 대한 설명 🫠

두 엔티티 간에 한 인스턴스가 여러 인스턴스와 연결될 수 있으며, 그 반대도 가능한 구조이다.예시로는 학생과 강의의 관계 - 한 학생은 여러 강의를 들을 수 있고, 한 강의는 여러 학생에게 가르칠 수 있다는걸 예로 들수있다.
N:M 관계의 특징

복잡성: N:M 관계는 관리해야 할 연결 정보가 많아 복잡해질 수 있다. 따라서, 이러한 관계를 효율적으로 처리하기 위해 보통 연결 테이블(또는 조인 테이블)을 사용한다.

연결 테이블: 두 엔티티 사이의 연결을 관리하기 위한 별도의 테이블로, 각 엔티티의 기본 키를 외래 키로 포함.

조인 엔티티: 연결 테이블에 해당하는 엔티티로, JPA에서는 이를 @ManyToMany 관계로 매핑.
JPA에서의 N:M 관계 구현

@ManyToMany: JPA에서는 @ManyToMany 어노테이션을 사용하여 다대다 관계를 나타낸다.
예시 코드:

@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ... 다른 필드들 ...

    @ManyToMany
    @JoinTable(
        name = "enrollment",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List<Course> courses = new ArrayList<>();
    // ...
}

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ... 다른 필드들 ...

    @ManyToMany(mappedBy = "courses")
    private List<Student> students = new ArrayList<>();
    // ...
}

위 코드에서 Student와 Course 엔티티는 다대다 관계를 가집니다. @JoinTable을 사용하여 연결 테이블 enrollment을 정의하고 있으며, joinColumns와 inverseJoinColumns를 사용하여 양쪽 엔티티의 외래 키를 지정.
N:M 관계의 처리 방법

조인 테이블 사용: 실제 데이터베이스 설계에서는 N:M 관계를 직접 구현하는 대신 조인 테이블을 사용하여 2개의 N:1 관계로 분리하여 처리.
성능 고려: 다대다 관계는 쿼리가 복잡해지고 성능에 영향을 줄 수 있으므로, 필요한 경우 추가적인 성능 최적화를 고려해야 한다.
N:M 관계는 데이터베이스 설계에서 흔히 볼 수 있는 중요한 패턴이다. 하지만, 이 관계는 처리가 복잡하고 성능상의 고려가 필요하기 때문에, 실제 애플리케이션 설계 시에는 다대다 관계를 피하거나, 양방향 관계를 단방향으로 전환하여 관리하는 방법을 고려하기도 한다.

회고 ✍️

오늘은 RestTemplate과 엔티티 관계 설정에 대해 깊이 있게 파고들었다. RestTemplate의 여러 메서드를 사용해보면서 REST API 통신이 얼마나 쉽고 간결해질 수 있는지 경험했다. 반면, 엔티티 관계 설정은 데이터베이스 설계의 중심이며, 올바른 설정은 애플리케이션의 데이터 흐름과 성능에 결정적인 영향을 미친다는 것을 깨달았다. 이 두 영역의 조화는 강력한 백엔드 시스템을 구축하는 데 있어서 필수 불가결한 요소라고 할 수 있다. 오늘 배운 지식을 바탕으로 더 나은 코드를 작성해 나가고자 한다.

profile
개발이란 무엇인가..를 공부하는 거북이의 성장일기 🐢

0개의 댓글