반응형
해당 글에서는 Spring Cloud OpenFeign을 활용하여 외부 통신을 활용하는 예시에 대해 알아봅니다.
💡 [참고] Java에서 외부 통신을 하는 방법들에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다
분류 | 주제 | 링크 |
RestTemplate | Spring Boot Web 활용 : RestTemplate 이해하기 | https://adjh54.tistory.com/234 |
WebClient | Spring Boot Webflux 이해하기 -1 : 흐름 및 주요 특징 이해 | https://adjh54.tistory.com/232 |
WebClient | Spring Boot Webflux 이해하기 -2 : 활용하기 | https://adjh54.tistory.com/233 |
Open Feign | Spring Cloud OpenFeign 이해하고 활용하기 -1 : 주요 개념 및 환경 구성, 활용 예시 | https://adjh54.tistory.com/616 |
Github | 외부 통신의 활용 방법을 담은 예제 Repository | https://github.com/adjh54ir/blog-codes/tree/main/spring-boot-external-network |
1) Spring Cloud OpenFeign
💡 Spring Cloud OpenFeign
- Netflix에서 개발한 HTTP 클라이언트 라이브러리를 Spring Cloud에서 통합한 선언적 HTTP 클라이언트 라이브러리입니다.
- Spring Cloud에서는 Open Feign을 스프링 MVC 어노테이션을 사용하여 웹 서비스 클라이언트를 쉽게 작성할 수 있도록 통합했습니다.
- OpenFeign은 마이크로서비스 아키텍처에서 특히 유용하며, 코드를 더 간결하고 유지보수하기 쉽게 만듭니다.
1. 주요 특징
특징 | 설명 |
선언적 REST 클라이언트 | 인터페이스와 어노테이션만으로 HTTP API 클라이언트를 작성할 수 있습니다. |
스프링 MVC 어노테이션 지원 | @RequestMapping, @PathVariable, @RequestParam 등 스프링 MVC 어노테이션을 그대로 사용할 수 있습니다. |
유연한 설정 | 인터셉터, 디코더, 인코더 등을 커스터마이징할 수 있습니다. |
로드 밸런싱 | Ribbon과 통합되어 클라이언트 사이드 로드 밸런싱을 지원합니다. |
서킷 브레이커 | Hystrix/Resilience4j와 통합하여 장애 허용 패턴을 구현할 수 있습니다. |
2. 외부 통신 클라이언트 비교 : RestTemplate, WebClient, OpenFeign
💡 외부 통신 클라이언트 비교 : RestTemplate, WebClient, OpenFeign
- Spring Boot 환경에서 사용하는 외부 통신 클라이언트로는 RestTemplate, WebClient, OpenFeign를 이용합니다. 각각에 대해서 비교해 봅니다.
1. RestTemplate
- Spring 3.0부터 제공된 전통적인 HTTP 클라이언트로 동기식으로 데이터 통신이 처리되며 응답을 받을 때까지 블로킹 방식으로 응답을 기다리는 통신이 이루어집니다.
2. WebClient
- WebFlux의 일부인 Webclient는 비동기적인 방식으로 HTTP 요청을 보내고 응답을 기다리지 않는 논-블로킹 방식으로 통신이 이루어집니다.
3. OpenFeign
- Spring Cloud의 일부인 OpenFeign는 선언적 REST 클라이언트로, 인터페이스와 어노테이션만으로 HTTP API 클라이언트를 작성하며 동기식으로 데이터 처리되며 응답을 받을 때까지 블로킹 방식으로 응답을 기다리는 통신이 이루어집니다.
특징 | RestTemplate | WebClient | OpenFeign |
구현 방식 | ‘명령형’ 방식으로 HTTP 요청을 직접 구현 | ‘함수형’ 방식으로 체이닝 구현 | ‘선언형’ 방식으로 인터페이스만 정의 |
코드 복잡도 | URL, HTTP 메서드, 요청/응답 처리를 모두 직접 작성 | 메서드 체이닝으로 직관적 구현 | 어노테이션 기반으로 간단하게 정의 |
비동기 지원 | 동기-블로킹 방식만 지원 | 비동기-논블로킹 방식 지원 | 동기-블로킹 방식만 지원 |
유지보수성 | 코드가 길어지고 반복적인 작성 필요 | 모듈화된 코드로 유지보수 용이 | 인터페이스 수정만으로 변경 가능 |
테스트 용이성 | MockRestServiceServer 사용 필요 | WebTestClient로 쉽게 테스트 | 인터페이스 기반으로 쉽게 Mock 가능 |
오류 처리 | try-catch로 직접 처리 필요 | onError() 등으로 선언적 처리 | ErrorDecoder로 중앙 집중적 처리 가능 |
로드밸런싱 | 별도 설정 필요 | LoadBalancerExchange 통합 | Ribbon과 통합되어 자동 지원 |
서킷브레이커 | 별도 구현 필요 | Resilience4j와 쉽게 통합 | Hystrix/Resilience4j와 쉽게 통합 |
💡[참고] 동기식 요청(Synchronous request) & 블로킹 요청(Blocking Request)
- 요청을 보내고 응답을 받을 때까지 블로킹되는 방식을 의미합니다.
💡 비동기식 요청(Asynchrouse Request) & 논 블로킹 요청(Non-Blocking Request)
- 요청을 보내고 응답을 받지 않는 논 블로킹 방식을 의미합니다.
2.1. RestTemplate 예시
💡 RestTemplate 예시
- 명령형 방식으로 HTTP 요청을 직접 구현해야 합니다.
- 아래와 같이 URL, HTTP Method, 요청/응답 데이터 지정 및 모든 처리에 대해서 작성해야 하며, 이는 코드가 길어지고 반복적인 작성이 필요합니다.
- RestTemplate 인스턴스를 생성하고 .getForObject() 메서드를 통해서 HTTP 요청을 수행합니다.
- 첫 번째 인자로는 호출 엔드포인트를 지정하고, 두 번째는 전송데이터를 지정, 마지막은 반환되는 타입을 지정합니다.
// RestTemplate 예시
@Service
public class UserService {
private final RestTemplate restTemplate;
private final String baseUrl = "http://api.example.com";
public User getUser(Long id) {
return restTemplate.getForObject(baseUrl + "/users/" + id, User.class);
}
}
💡[참고] RestTemplate에 대해 궁금하시면 아래의 글을 참고하시면 됩니다.
2.2. WebClient
💡 WebClient 예시
- 함수형 방식으로 HTTP 요청을 메서드 체이닝 방식을 통해서 구현해야 합니다
- 메서드 체이닝 방식을 사용하기에 직관적이고 간결한 코드를 확인할 수 있습니다.
- WebClient 인스턴스를 생성하고 .create 메서드를 통해서 통신하려는 도메인을 지정합니다.
- .get()는 HTTP Method를 지정하며, .url을 통해 엔드포인트를 지정하고 값을 전달하는 방식입니다.
// WebClient 예시
@Service
public class UserService {
private final WebClient webClient;
public UserService() {
this.webClient = WebClient.create("http://api.example.com");
}
public Mono getUser(Long id) {
return webClient.get()
.uri("/users/{id}", id)
.retrieve()
.bodyToMono(User.class);
}
}
💡 [참고] 메서드 체이닝에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
2.3. OpenFeign
💡OpenFeign
- 선언형 방식으로 인터페이스 내에 메서드와 어노테이션을 기반으로 HTTP 요청에 대한 구현을 합니다.
- 아래와 같이 구현한 인터페이스의 파라미터, 리턴타입을 지정하고 URL만 매핑하면 외부 통신을 수행할 수 있습니다.
- 자세한 내용은 해당 글의 아래의 예시에서 확인해 볼 수 있습니다.
// OpenFeign 예시
@FeignClient(name = "user-service", url = "http://api.example.com")
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") Long id);
}
💡 [참고] RestTemplate과 Webflux에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
3. 주요 어노테이션 확인하기
3.1. @EnableFeignClients
💡 @EnableFeignClients
- 주로 메인 애플리케이션 클래스나 구성 클래스 내에 선언하며, @ComponentScan과 유사하게 작동하여 @FeignClient가 선언된 인터페이스들을 찾아내는 역할을 수행합니다.
- 찾아낸 구현체를 Spring Bean에 등록하여 Open Feign 관련 자동구성을 활성화합니다.
💡 @EnableFeignClients 속성
속성 | 리턴 타입 | 설명 |
value | Class<?><[]> | FeignClient를 스캔할 패키지들을 지정 |
basePackages | String[] | value와 동일한 역할을 하며 FeignClient를 스캔할 패키지 지정 |
basePackageClasses | Class<?><[]> | 지정된 클래스들이 있는 패키지를 스캔 |
defaultConfiguration | Class<?><[]> | 모든 Feign 클라이언트에 적용될 기본 구성 클래스 지정 |
clients | String[] | 특정 FeignClient 클래스들만 등록하도록 명시적으로 지정 |
💡 @EnableFeignClients 어노테이션 속성 예시
- 아래와 같이 @FeignClient가 선언된 스캔을 위해 basePackages 속성으로 패키지를 지정하거나 defaultConfiguration 속성으로 특정 클래스를 지정합니다.
- 기본적으로 @EnableFeignClients 속성 없이 선언하는 경우 모든 패키지나 클래스를 스캔합니다.
@EnableFeignClients(
basePackages = "com.example.clients",
defaultConfiguration = DefaultFeignConfig.class
)
@SpringBootApplication
public class Application {
// ...
}
3.2. @FeignClient
💡 @FeignClient
- HTTP 클라이언트를 생성하기 위한 인터페이스를 선언하는 어노테이션입니다. 이 어노테이션을 사용하면 REST API를 호출하는 인터페이스를 쉽게 정의할 수 있습니다.
- 선언만으로 REST 클라이언트를 정의하며, Spring Runtime 단계에서 해당 인터페이스의 구현체를 자동으로 생성합니다.
- @GetMapping, @PostMapping 등의 Spring MVC 어노테이션을 그대로 사용할 수 있습니다.
💡 [참고] @FeignClient 속성
속성 | 리턴 타입 | default value | 설명 |
name | String | - | FeignClient의 이름을 지정합니다. (필수) |
url | String | "" | 대상 서버의 URL을 지정합니다. |
configuration | Class<?>[] | FeignClientsConfiguration.class | FeignClient에 대한 사용자 정의 구성 클래스 지정합니다. |
fallback | Class<?> | void.class | 장애 발생 시 대체할 구현 클래스 지정합니다. |
fallbackFactory | Class<?> | void.class | 동적 fallback 객체 생성을 위한 Factory 클래스 지정합니다. |
path | String | "" | 모든 메서드에 적용될 공통 prefix 경로를 지정합니다. |
decode404 | boolean | false | 404 응답을 에러로 처리할지 여부를 지정합니다. |
primary | boolean | true | 동일한 타입의 여러 빈이 있을 때 우선 선택할지 여부를 지정합니다. |
💡@FeignClient 어노테이션 속성 예시
- name 속성: name = "user-service": Feign 클라이언트의 이름을 지정
- url 속성: url = "http://api.example.com": 요청을 보낼 대상 서버의 기본 URL을 지정
- @GetMapping("/users/{id}"): HTTP GET 요청을 위한 메서드로, 특정 사용자 정보를 조회
- @PostMapping("/users"): HTTP POST 요청을 위한 메서드로, 새로운 사용자를 생성
@FeignClient(name = "user-service", url = "http://api.example.com")
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") Long id);
@PostMapping("/users")
User createUser(@RequestBody User user);
}
반응형
2) Spring Cloud OpenFeign 환경설정
1. 개발 환경
개발 환경 | 버전 |
java | 17 |
spring boot | 3.3.6 |
spring-boot-starter-web | 3.3.6 |
spring-cloud-starter-openfeign | 4.1.3 |
spring-cloud-dependencies | 2023.0.3 |
lombok | - |
💡[참고] 무료로 REST API를 테스트해볼 수 있는 JSONPlaceholder 페이지를 통해서 데이터 통신 테스트를 수행합니다.
- 공통 도메인 주소는 https://jsonplaceholder.typicode.com/입니다. REST API 형태로 테스트를 위해 호출이 가능합니다.
엔드포인트 | HTTP Method | 설명 |
/posts | GET, POST, PUT, DELETE | 게시글 데이터 조회 |
/comments | GET, POST, PUT, DELETE | 댓글 데이터 조회 |
/albums | GET, POST, PUT, DELETE | 앨범 데이터 조회 |
/photos | GET, POST, PUT, DELETE | 사진 데이터 조회 |
/todos | GET, POST, PUT, DELETE | 할일 데이터 조회 |
/users | GET, POST, PUT, DELETE | 사용자 데이터 조회 |
2. 의존성 추가
💡 의존성 추가
- Spring Cloud OpenFeign을 이용하기 위한 “spring-cloud-starter-openfeign”라이브러리를 추가해야 합니다.
- 또한, org.springframework.cloud:spring-cloud-dependencies도 함께 추가해야 합니다. 이를 추가하는 이유는 OpenFeign의 경우 Spring Cloud의 다른 컴포넌트들과 함께 작동하기 위해서 추가해야 합니다.
- 해당 프로젝트에서는 3.3.6 버전을 기준으로 구성하였기에 2023.0.3을 버전을 사용합니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.6'
id 'io.spring.dependency-management' version '1.1.6'
}
ext {
set('springCloudVer', "2023.0.3")
}
dependencies {
implementation "org.springframework.cloud:spring-cloud-starter-openfeign:4.1.3"
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVer}"
}
}
Maven Repository: org.springframework.cloud » spring-cloud-starter-openfeign
💡 [참고] org.springframework.cloud:spring-cloud-dependencies는 무슨 버전으로 받아야 할까?
- 공식 사이트의 표에 따르면 아래와 같이 Spring Boot Version에 따라서 Spring Cloud 지원 버전이 달라집니다.
- 해당 글에서는 가장 최신 버전이 되는 Spring Boot 3.4.0 버전을 사용하기에 2023.0.3 버전을 이용하여 의존성을 추가하였습니다.
Maven Repository: org.springframework.cloud » spring-cloud-dependencies
3. xxApplication.java 설정
💡 xxApplication.java 설정
- @FeignClient 어노테이션이 적용된 인터페이스들을 스캔하여 빈으로 등록합니다.
- @FeignClient 어노테이션의 속성 basePackages 설정하여 특정 패키지만 스캔하도록 basePackages 속성을 통해 스캔 범위를 지정할 수 있습니다.
package com.adjh.springbootexternalcmnc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients // FeignClient 사용을 선언합니다.
@SpringBootApplication
public class SpringBootExternalCmncApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootExternalCmncApplication.class, args);
}
}
4. xxSerivce.java(interface) 설정
💡 xxSerivce.java(interface) 설정
- Spring Cloud OpenFeign을 사용하여서 “https://jsonplaceholder.typicode.com”와의 외부 통신을 위해 interface를 구성하였습니다.
- 해당 서비스 페이지에서 함수 구성 및 통신을 함께 진행합니다.
package com.adjh.springbootexternalnetwork.service;
import com.adjh.springbootexternalnetwork.dto.PostResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
/**
* json placeholder 외부 통신을 하는 예시
*
* @author : jonghoon
* @fileName : OpenFeignService
* @since : 11/23/24
*/
@FeignClient(
name = "json placeholder",
url = "<https://jsonplaceholder.typicode.com>"
)
public interface OpenFeignService {
@GetMapping("/posts")
List getPosts();
@GetMapping("/posts/{id}")
PostResponseDto getPostById(@PathVariable("id") String id);
}
5. xxController.java 설정
💡 xxController.java 설정
- 특정 엔드포인트를 OpenFeign을 이용한 인터페이스 서비스를 호출하여 반환해 주는 Controller가 구성되었습니다.
package com.adjh.springbootexternalnetwork.controller;
import com.adjh.springbootexternalnetwork.service.OpenFeignService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* OpenFeign 테스트 Controller
*
* @author : jonghoon
* @fileName : OpenFeignController
* @since : 11/24/24
*/
@RestController
@RequestMapping("api/v1/openFeign")
public class OpenFeignController {
private final OpenFeignService openFeignService;
public OpenFeignController(OpenFeignService openFeignService) {
this.openFeignService = openFeignService;
}
/**
* 게시물을 전체를 조회합니다.
*
* @return
*/
@PostMapping("/getPosts")
public ResponseEntity<Object> getPosts() {
Object resultObj = openFeignService.getPosts();
return new ResponseEntity<>(resultObj, HttpStatus.OK);
}
/**
* 특정 게시물을 조회합니다.
*
* @param postId
* @return
*/
@PostMapping("/getPost/{postId}")
public ResponseEntity<Object> getPostById(@PathVariable String postId) {
Object resultObj = openFeignService.getPostById(postId);
return new ResponseEntity<>(resultObj, HttpStatus.OK);
}
}
6. 결과 확인
💡 결과 확인
- 아래와 같이 API 호출을 하였을 때, 아래와 같이 결과를 반환해 줌을 확인하였습니다.
3) Spring Cloud OpenFegin 활용하기 -1 : 추가 비즈니스 로직 처리
💡 Spring Cloud OpenFegin 활용하기 -1 : 추가 비즈니스 로직 처리
- 기존의 인터페이스 형태로 받아온 응답 값에 대해서 추가적인 비즈니스 로직 처리를 수행하여 사용자에게 반환해 주는 부분을 추가합니다.
1. xxService.java : interface
💡 xxService.java : interface
- https://jsonplaceholder.typicode.com와 통신하여 받아오는 OpenFeign을 정의하였습니다.
package com.adjh.springbootexternalnetwork.service;
import com.adjh.springbootexternalnetwork.dto.PostResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
/**
* json placeholder 외부 통신을 하는 예시
*
* @author : jonghoon
* @fileName : OpenFeignService
* @since : 11/23/24
*/
@FeignClient(name = "json-placeholder", url = "<https://jsonplaceholder.typicode.com>")
public interface OpenFeignService {
@GetMapping("/posts")
List getPosts();
@GetMapping("/posts/{id}")
PostResponseDto getPostById(@PathVariable("id") String id);
}
2. 추가 비즈니스 로직 처리 : class
💡 추가 비즈니스 로직 처리 : class
- OpenFeignService 인터페이스의 인스턴스를 생성하여서 해당 서비스의 값을 받아서 추가적인 비즈니스 로직을 구성합니다.
- getFilteredPosts()의 경우는 게시물 id가 30 초과인 경우로 필터링을 적용하여 비즈니스 로직 처리를 하였습니다.
- getFilterBodySummary() 경우는 body 값이 100자가 초과되는 경우 “…” 처리를 수행하며, 초과되지 않는 경우는 기존의 값을 그대로 리턴합니다.
package com.adjh.springbootexternalnetwork.service;
import com.adjh.springbootexternalnetwork.dto.PostResponseDto;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* OpenFeign 통신을 통해 가져온 응답 값을 통해 비즈니스 로직을 처리합니다.
*/
@Service
public class OpenFeignBusinessService {
private final OpenFeignService openFeignService;
public OpenFeignBusinessService(OpenFeignService openFeignService) {
this.openFeignService = openFeignService;
}
// 특정 조건으로 게시물 필터링
public List<PostResponseDto> getFilteredPosts() {
List<PostResponseDto> posts = openFeignService.getPosts();
return posts.stream()
.filter(post -> post.getId() > 30)
.collect(Collectors.toList());
}
// 게시물 데이터 가공
public PostResponseDto getFilterBodySummary(String id) {
PostResponseDto post = openFeignService.getPostById(id);
// 컨텐츠 요약 추가
if (post.getBody().length() > 100) {
post.setBody(post.getBody().substring(0, 100) + "...");
} else {
post.setBody(post.getBody());
}
// 추가 데이터 처리 로직
return post;
}
}
3. 결과 확인
💡결과 확인
- 아래와 같이 게시물 아이디가 30 초과인 리스트 값만 출력하도록 필터링에 대한 비즈니스로직을 구성하였습니다.
💡 아래와 같이 게시물 문자열 길이가 100자 초과인 경우 “…”을 적용하여 출력하도록 하였습니다.
4) Spring Cloud OpenFeign 활용하기 -2 : Header 설정
💡 Spring Cloud OpenFeign Header 설정
- OpenFeign를 통해 데이터 통신을 수행할 때, 추가적인 Header를 보내야 하는 경우도 있습니다. 이 경우를 위해서 Header를 설정하는 방법에 대해서 알아봅니다.
1. @RequestHeader 사용하는 방법
💡@RequestHeader 사용하는 방법
- 메서드 별로 직접 헤더를 지정하는 방식을 의미합니다. 이는 각 API 호출마다 다른 헤더값이 필요한 경우에 유용합니다.
- @RequestHeader 어노테이션을 통해 메서드 파라미터로 헤더값을 전달할 수 있습니다. 인증 토큰과 같이 동적으로 변하는 헤더값을 처리하기에 적합합니다.
💡 @RequestHeader 해당 예시
- https://jsonplaceholder.typicode.com 사이트에 Header를 전달하는 방식입니다.
- /todos 엔드포인트에서는 header로 Authorization 값을 전달합니다.
- todos/{id} 엔드포인트에서는 header로 Authorization, x-refresh-token를 전달하고, todos/{id} 형태로 id 값을 전달합니다.
package com.adjh.springbootexternalnetwork.service;
import com.adjh.springbootexternalnetwork.dto.PostResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.List;
/**
* json placeholder 외부 통신을 하는 예시
*
* @author : jonghoon
* @fileName : OpenFeignService
* @since : 11/23/24
*/
@FeignClient(name = "json-placeholder", url = "<https://jsonplaceholder.typicode.com>")
public interface OpenFeignService {
@GetMapping("/todos")
List getTodosAddHeader(@RequestHeader("Authorization") String token);
@GetMapping("/todos/{id}")
PostResponseDto getTodoAddHeader(
@RequestHeader("Authorization") String authToken,
@RequestHeader("x-refresh-token") String refreshToken,
@PathVariable("id") String id);
}
💡OpenFeignController
- 두 개의 엔드포인트는 동일하게 @RequestHeader를 클라이언트로부터 받아오도록 구성하였습니다.
package com.adjh.springbootexternalnetwork.controller;
import com.adjh.springbootexternalnetwork.service.OpenFeignBusinessService;
import com.adjh.springbootexternalnetwork.service.OpenFeignService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* OpenFeign 테스트 Controller
*
* @author : jonghoon
* @fileName : OpenFeignController
* @since : 11/24/24
*/
@RestController
@RequestMapping("api/v1/openFeign")
public class OpenFeignController {
private final OpenFeignService openFeignService;
private final OpenFeignBusinessService openFeignBusinessService;
public OpenFeignController(OpenFeignService openFeignService, OpenFeignBusinessService openFeignBusinessService) {
this.openFeignService = openFeignService;
this.openFeignBusinessService = openFeignBusinessService;
}
/**
* 게시물을 전체를 조회합니다.
*
* @return
*/
@PostMapping("/getTodos")
public ResponseEntity<Object> getPostsAddHeader(@RequestHeader("Authorization") String token) {
Object resultObj = openFeignService.getTodosAddHeader(token);
return new ResponseEntity<>(resultObj, HttpStatus.OK);
}
/**
* 특정 게시물을 조회합니다.
*
* @param postId
* @return
*/
@PostMapping("/getTodo/{postId}")
public ResponseEntity<Object> getPostByIdAddHeader(
@RequestHeader("Authorization") String token,
@RequestHeader("x-refresh-token") String refreshToken,
@PathVariable String postId) {
Object resultObj = openFeignService.getTodoAddHeader(token, refreshToken, postId);
return new ResponseEntity<>(resultObj, HttpStatus.OK);
}
}
💡사용 결과 확인 : @GetMapping("/todos")
- todos 해당 API 호출 시 Authorization가 필요하다는 전제로 header에 추가하여 전송하여 통신에 성공하였습니다.
💡 사용 결과 확인: @GetMapping("/todos/{id}")
- todos 해당 API 호출 시 Authorization와 커스텀 해더인 “x-refresh-token”가 필요하다는 전제로 header에 추가하여 전송하여 통신에 성공하였습니다.
오늘도 감사합니다. 😀
반응형