๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๋ฐฑ์—”๋“œ/spring&springboot

[๋‚ด์ผ๋ฐฐ์›€์บ ํ”„_Spring Boot ์ˆ™๋ จ์ฃผ์ฐจ] RestTemplate & Open API

by alswlfl 2026. 6. 30.

RestTemplate์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ?

Server To Server

  • ์ง€๊ธˆ๊นŒ์ง€๋Š” ๋ธŒ๋ผ์šฐ์ € Client๋กœ๋ถ€ํ„ฐ ์š”์ฒญ์„ ๋ฐ›๋Š” ์„œ๋ฒ„์˜ ์ž…์žฅ์—์„œ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•ด์™”์Œ
  • ์„œ๋น„์Šค ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋‹ค๋ณด๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ๋งŒ์œผ๋กœ๋Š” ๊ตฌํ˜„์ด ํž˜๋“  ๊ธฐ๋Šฅ๋“ค์ด ๋ฌด์ˆ˜ํžˆ ๋งŽ์ด ์กด์žฌํ•จ
    ex) ํšŒ์›๊ฐ€์ž…์„ ์ง„ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ์ž์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ›์•„์•ผ ํ•œ๋‹ค๋ฉด, ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ง์ ‘ ๊ตฌํ˜„์„ ํ•˜๊ฒŒ ๋˜๋ฉด ๋งŽ์€ ์‹œ๊ฐ„๊ณผ ๋น„์šฉ์ด ๋“ค์–ด๊ฐ
  • ์ด๋•Œ, ์นด์นด์˜ค์—์„œ ๋งŒ๋“  ์ฃผ์†Œ ๊ฒ€์ƒ‰ API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์šฐ๋ฆฌ์˜ ์„œ๋ฒ„๋Š” Client ์ž…์žฅ์ด ๋˜์–ด Kakao ์„œ๋ฒ„์— ์š”์ฒญ์„ ์ง„ํ–‰ํ•ด์•ผ ํ•จ

Server To Server

 

Spring์—์„œ๋Š” ์„œ๋ฒ„์—์„œ ๋‹ค๋ฅธ ์„œ๋ฒ„๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋„๋ก RestTemplate ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Œ

Client ์ž…์žฅ์˜ Server(์ดˆ๊ธฐ์„ธํŒ…) 

  • Client ์ž…์žฅ์˜ Server ํฌํŠธ ๋ฒˆํ˜ธ: 8080

Controller

package com.sparta.springresttemplateclient.controller;

import com.sparta.springresttemplateclient.dto.ItemDto;
import com.sparta.springresttemplateclient.service.RestTemplateService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/client")
public class RestTemplateController {

    private final RestTemplateService restTemplateService;

    public RestTemplateController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/get-call-obj")
    public ItemDto getCallObject(String query) {
        return restTemplateService.getCallObject(query);
    }

    @GetMapping("/get-call-list")
    public List<ItemDto> getCallList() {
        return restTemplateService.getCallList();
    }

    @GetMapping("/post-call")
    public ItemDto postCall(String query) {
        return restTemplateService.postCall(query);
    }

    @GetMapping("/exchange-call")
    public List<ItemDto> exchangeCall(@RequestHeader("Authorization") String token) {
        return restTemplateService.exchangeCall(token);
    }
}

 

DTO

package com.sparta.springresttemplateclient.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class ItemDto {
    private String title;
    private int price;
}

 

Entity

package com.sparta.springresttemplateclient.entity;

import lombok.Getter;

@Getter
public class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

 

Service

package com.sparta.springresttemplateclient.service;

import com.sparta.springresttemplateclient.dto.ItemDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class RestTemplateService {

    public ItemDto getCallObject(String query) {
        return null;
    }

    public List<ItemDto> getCallList() {
        return null;
    }

    public ItemDto postCall(String query) {
        return null;
    }

    public List<ItemDto> exchangeCall(String token) {
        return null;
    }
}

 

๏นก์ˆœ์„œ ํ๋ฆ„: Client ์ž…์žฅ์˜ Server์˜ Controller๋กœ ์š”์ฒญ → Service๋ฅผ ๊ฑฐ์ณ Server ์ž…์žฅ์˜ Server๋กœ ์š”์ฒญ์ด ๋ณด๋‚ด์ง(RestTemplate์„ ์‚ฌ์šฉ) → ์š”์ฒญ์— ๊ด€ํ•œ ๋กœ์ง ์ฒ˜๋ฆฌ ํ›„ ์‘๋‹ต ๋ฐ˜ํ™˜ → ๋‹ค์‹œ Client ์ž…์žฅ์˜ Server๋ฅผ ํ†ตํ•ด ์ตœ์ข…์ ์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›์Œ

Server ์ž…์žฅ์˜ Server(์ดˆ๊ธฐ์„ธํŒ…) 

  • Server ์ž…์žฅ์˜ Server ํฌํŠธ ๋ฒˆํ˜ธ: 7070
  • ํ•ด๋‹น ์„œ๋ฒ„๋Š” Client ์ž…์žฅ์˜ Server๊ฐ€ ๋ณด๋‚ธ ์š”์ฒญ์„ ๋ฐ›๋Š” Controller
// application.properties
server.port = 7070

 

Controller

package com.sparta.springresttemplateserver.controller;

import com.sparta.springresttemplateserver.dto.ItemResponseDto;
import com.sparta.springresttemplateserver.dto.UserRequestDto;
import com.sparta.springresttemplateserver.entity.Item;
import com.sparta.springresttemplateserver.service.ItemService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/server")
public class ItemController {

    private final ItemService itemService;

    public ItemController(ItemService itemService) {
        this.itemService = itemService;
    }

    @GetMapping("/get-call-obj")
    public Item getCallObject(@RequestParam String query) {
        return itemService.getCallObject(query);
    }

    @GetMapping("/get-call-list")
    public ItemResponseDto getCallList() {
        return itemService.getCallList();
    }

    @PostMapping("/post-call/{query}")
    public Item postCall(@PathVariable String query, @RequestBody UserRequestDto requestDto) {
        return itemService.postCall(query, requestDto);
    }

    @PostMapping("/exchange-call")
    public ItemResponseDto exchangeCall(@RequestHeader("X-Authorization") String token, @RequestBody UserRequestDto requestDto) {
        return itemService.exchangeCall(token, requestDto);
    }
}

 

DTO

package com.sparta.springresttemplateserver.dto;

import com.sparta.springresttemplateserver.entity.Item;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemResponseDto {
    private final List<Item> items = new ArrayList<>();

    public void setItems(Item item) {
        items.add(item);
    }
}
package com.sparta.springresttemplateserver.dto;

import lombok.Getter;

@Getter
public class UserRequestDto {
    private String username;
    private String password;
}

 

Entity

package com.sparta.springresttemplateserver.entity;

import lombok.Getter;

@Getter
public class Item {
    private String title;
    private int price;

    public Item(String title, int price) {
        this.title = title;
        this.price = price;
    }
}

 

Service

package com.sparta.springresttemplateserver.service;

import com.sparta.springresttemplateserver.dto.ItemResponseDto;
import com.sparta.springresttemplateserver.dto.UserRequestDto;
import com.sparta.springresttemplateserver.entity.Item;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
public class ItemService {

    private final List<Item> itemList = Arrays.asList(
            new Item("Mac", 3_888_000),
            new Item("iPad", 1_230_000),
            new Item("iPhone", 1_550_000),
            new Item("Watch", 450_000),
            new Item("AirPods", 350_000)
    );

    public Item getCallObject(String query) {
        return null;
    }

    public ItemResponseDto getCallList() {
        return null;
    }

    public Item postCall(String query, UserRequestDto requestDto) {
        return null;
    }

    public ItemResponseDto exchangeCall(String token, UserRequestDto requestDto) {
        return null;
    }
}

RestTemplate์˜ Get ์š”์ฒญ

๊ฐ์ฒด ํ•˜๋‚˜๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

Client ์ž…์žฅ์˜ Server

  • RestTemplate ์ฃผ์ž… ๋ฐ›์•„์™€ ์‚ฌ์šฉํ•˜๊ธฐ
// RestTemplateService

...
@Slf4j
@Service
public class RestTemplateService {

    private final RestTemplate restTemplate;

    // RestTemplate์„ Spring Boot์—์„œ ์ž๋™ ๋“ฑ๋ก์„ ์ฒ˜์Œ์— ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Œ
    // ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— RestTemplate์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” RestTemplate builder๋ฅผ ๋“ฑ๋กํ•ด์ค˜์•ผํ•จ
    public RestTemplateService(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }


	...
}
  • Client ์ชฝ GET ์š”์ฒญ ๋งŒ๋“ค๊ธฐ
// RestTemplateService.java
public ItemDto getCallObject(String query) {
    // ์š”์ฒญ URL ๋งŒ๋“ค๊ธฐ
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070") // ์„œ๋ฒ„ ์ž…์žฅ์˜ ์„œ๋ฒ„์— ๋ณด๋‚ผ ์ค€๋น„
            .path("/api/server/get-call-obj") // ์„œ๋ฒ„ ์ž…์žฅ์˜ ์„œ๋ฒ„์˜ Controller ๋ถ€๋ถ„
            .queryParam("query", query) // ?๊ฒ€์ƒ‰์–ด
            .encode()
            .build()
            .toUri();
    log.info("uri = " + uri);

    // GET ๋ฐฉ์‹์œผ๋กœ ํ•ด๋‹น URI ์„œ๋ฒ„์— ์š”์ฒญ์ด ๋ณด๋‚ด์ง
    // getForEntity(URI, ์š”์ฒญ์„ ํ•œ ๋‹ค์Œ ๋ฐ›์„ ์‘๋‹ต DTO);
    // :๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์„œ๋ฒ„์˜ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋„˜์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์ค„ Class ํƒ€์ž…์„ ์ง€์ •ํ•˜๋ฉด, ์ž๋™์œผ๋กœ ์—ญ์ง๋ ฌํ™”๊ฐ€ ๋˜์–ด์„œ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋‹ด๊น€
    ResponseEntity<ItemDto> responseEntity = restTemplate.getForEntity(uri, ItemDto.class);

    log.info("statusCode = " + responseEntity.getStatusCode());

    return responseEntity.getBody();
}

 

Server ์ž…์žฅ์˜ Server

// ItemService
// ๊ฒ€์ƒ‰์–ด์— ํ•ด๋‹นํ•˜๋Š” Item ๋ฐ˜ํ™˜
public Item getCallObject(String query) {
    for (Item item : itemList) {
        if(item.getTitle().equals(query)) {
            return item;
        }
    }
    return null;
}

๊ฒฐ๊ณผ
Client ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„

 

๊ฐ์ฒด ์—ฌ๋Ÿฌ๊ฐœ ๊ฐ€์ ธ์˜ค๊ธฐ

Client ์ž…์žฅ์˜ Server

  • JSON์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด dependencies์— ์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€
// json
implementation 'org.json:json:20230227'
  • RestTemplateService์— ๊ฐ์ฒด ์—ฌ๋Ÿฌ๊ฐœ ๊ฐ€์ ธ์˜ค๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ์ฝ”๋“œ ์ถ”๊ฐ€
    - ์—ฌ๋Ÿฌ๊ฐœ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด String ๊ฐ์ฒด๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ
package com.sparta.springresttemplateclient.service;

...

@Slf4j
@Service
public class RestTemplateService {

	...

    public List<ItemDto> getCallList() {
        // ์š”์ฒญ URL ๋งŒ๋“ค๊ธฐ
        URI uri = UriComponentsBuilder
                .fromUriString("http://localhost:7070")
                .path("/api/server/get-call-list")
                .encode()
                .build()
                .toUri();
        log.info("uri = " + uri);

        ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class); // ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด String์œผ๋กœ ๋ฐ›์•„์˜ค๊ธฐ

        log.info("statusCode = " + responseEntity.getStatusCode());
        log.info("Body = " + responseEntity.getBody());

        return fromJSONtoItems(responseEntity.getBody());
    }
	...

//    ๋„˜์–ด์˜ค๋Š” JSON ํ˜•ํƒœ(์ค‘์ฒฉ JSON)
//    {
//        "items": [
//        {"title":"Mac", "price": 3888000},
//        {"title":"iPad", "price": 1230000},
//        {"title":"iPhone", "price": 1550000},
//        {"title":"Watch", "price": 450000},
//        {"title":"AirPods", "price": 350000}
//        ]
//    }
    public List<ItemDto> fromJSONtoItems(String responseEntity) {
        // JSONObject์˜ getJSONArray ๋ฉ”์„œ๋“œ์— key๊ฐ’์„ ์ฃผ๊ธฐ
        JSONObject jsonObject = new JSONObject(responseEntity);
        JSONArray items  = jsonObject.getJSONArray("items");
        List<ItemDto> itemDtoList = new ArrayList<>();

        for (Object item : items) {
            ItemDto itemDto = new ItemDto((JSONObject) item);
            itemDtoList.add(itemDto);
        }

        return itemDtoList;
    }
}
  • ItemDto์— ์ƒ์„ฑ์ž ์ถ”๊ฐ€
package com.sparta.springresttemplateclient.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import org.json.JSONObject;

@Getter
@NoArgsConstructor
public class ItemDto {
    private String title;
    private int price;

    public ItemDto(JSONObject itemJson) {
        this.title = itemJson.getString("title");
        this.price = itemJson.getInt("price");
    }
}

 

Server ์ž…์žฅ์˜ Server

// ItemService.java ๋‚ด ์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€
public ItemResponseDto getCallList() {
    ItemResponseDto responseDto = new ItemResponseDto();
    for (Item item : itemList) {
        responseDto.setItems(item);
    }
    return responseDto;
}

๊ฒฐ๊ณผ
Client ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„


RestTemplate์˜ Post ์š”์ฒญ

Client ์ž…์žฅ์˜ Server

// RestTemplateService.java
public ItemDto postCall(String query) {
    // ์š”์ฒญ URL ๋งŒ๋“ค๊ธฐ
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070")
            .path("/api/server/post-call/{query}") // Path Variable ๋ฐฉ์‹
            .encode()
            .build()
            .expand(query)
            .toUri();
    log.info("uri = " + uri);

    User user = new User("Robbie", "1234");

    // postForEntity(URI, HttpBody์— ๋„ฃ์–ด์ค„ ๋ฐ์ดํ„ฐ, ์ „๋‹ฌ๋ฐ›์„ ๋ฐ์ดํ„ฐ์™€ mappingํ•  ๊ฒƒ)
    // ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” RestTemplate์ด ์ž๋™์œผ๋กœ JSON์œผ๋กœ ๋ณ€๊ฒฝํ•ด์คŒ
    ResponseEntity<ItemDto> responseEntity = restTemplate.postForEntity(uri, user, ItemDto.class);

    log.info("statusCode = " + responseEntity.getStatusCode());

    return responseEntity.getBody();
}

 

Server ์ž…์žฅ์˜ Server

// ItemService.java
public Item postCall(String query, UserRequestDto userRequestDto) {
    System.out.println("userRequestDto.getUsername() = " + userRequestDto.getUsername());
    System.out.println("userRequestDto.getPassword() = " + userRequestDto.getPassword());

    return getCallObject(query);
}

๊ฒฐ๊ณผ
Client ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„
Server ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„


RestTemplate์˜ exchange

Header์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์„œ ์š”์ฒญํ•˜๋Š” ๋ฐฉ๋ฒ•

Client ์ž…์žฅ์˜ Server

// RestTemplateService
public List<ItemDto> exchangeCall(String token) {
    // ์š”์ฒญ URL ๋งŒ๋“ค๊ธฐ
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070")
            .path("/api/server/exchange-call")
            .encode()
            .build()
            .toUri();
    log.info("uri = " + uri);

    User user = new User("Robbie", "1234"); // Body์— ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ

    RequestEntity<User> requestEntity = RequestEntity
            .post(uri) // Method ์ง€์ •
            .header("X-Authorization", token) // Header ์ถ”๊ฐ€
            .body(user); // body ๋ถ€๋ถ„

    // exchange(RequestEntity ๊ฐ์ฒด, ๋ฐ›์•„์˜ฌ ๊ฐ์ฒด)
    ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);

    return fromJSONtoItems(responseEntity.getBody());
}

 

Server ์ž…์žฅ์˜ Server

// ItemService.java
public ItemResponseDto exchangeCall(String token, UserRequestDto requestDto) {
    System.out.println("token = " + token);
    System.out.println("requestDto.getUsername() = " + requestDto.getUsername());
    System.out.println("requestDto.getPassword() = " + requestDto.getPassword());

    return getCallList();
}

๊ฒฐ๊ณผ
Client ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„
Server ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„


Naver Open API

๋„ค์ด๋ฒ„๊ฐ€ ์ œ๊ณตํ•˜๋Š” API ๋ชฉ๋ก

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก

1-1) Postman์œผ๋กœ Naver API ์š”์ฒญํ•ด๋ณด๊ธฐ

  • Client ID์™€ Client Secret ๊ฐ’ ๋„ฃ์–ด์ค˜์•ผํ•จ

๊ฒฐ๊ณผ

2. Client ์ž…์žฅ์˜ ์„œ๋ฒ„์— Naver ์ƒํ’ˆ ๊ฒ€์ƒ‰ API ๊ธฐ๋Šฅ ๋ถ™์ด๊ธฐ

ํ๋ฆ„

DTO ์ƒ์„ฑ

์‘๋‹ต ์˜ˆ์‹œ(์ถœ์ฒ˜: https://developers.naver.com/docs/serviceapi/search/shopping/shopping.md#%EC%87%BC%ED%95%91)

package com.sparta.springresttemplateclient.naver.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import org.json.JSONObject;

@Getter
@NoArgsConstructor
public class ItemDto {
    private String title;
    private String link;
    private String image;
    private int lprice;

    public ItemDto(JSONObject itemJson) {
        this.title = itemJson.getString("title");
        this.link = itemJson.getString("link");
        this.image = itemJson.getString("image");
        this.lprice = itemJson.getInt("lprice");
    }
}

 

Controller ๊ตฌํ˜„

package com.sparta.springresttemplateclient.naver.controller;

import com.sparta.springresttemplateclient.naver.dto.ItemDto;
import com.sparta.springresttemplateclient.naver.service.NaverApiService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api")
public class NaverApiController {

    private final NaverApiService naverApiService;

    public NaverApiController(NaverApiService naverApiService) {
        this.naverApiService = naverApiService;
    }

    @GetMapping("/search")
    public List<ItemDto> searchItems(@RequestParam String query)  {
        return naverApiService.searchItems(query);
    }
}

 

Service ๊ตฌํ˜„

์š”์ฒญ ์˜ˆ์‹œ(์ถœ์ฒ˜: https://developers.naver.com/docs/serviceapi/search/shopping/shopping.md#%EC%87%BC%ED%95%91)

package com.sparta.springresttemplateclient.naver.service;

import com.sparta.springresttemplateclient.naver.dto.ItemDto;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

@Slf4j(topic = "NAVER API")
@Service
public class NaverApiService {

    private final RestTemplate restTemplate;

    public NaverApiService(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }

    public List<ItemDto> searchItems(String query) {
        // ์š”์ฒญ URL ๋งŒ๋“ค๊ธฐ
        URI uri = UriComponentsBuilder
                .fromUriString("https://openapi.naver.com")
                .path("/v1/search/shop.json")
                .queryParam("display", 15) // 15๊ฐœ์”ฉ ๊ฐ€์ ธ์˜ค(Default: 10)
                .queryParam("query", query)
                .encode()
                .build()
                .toUri();
        log.info("uri = " + uri);

        RequestEntity<Void> requestEntity = RequestEntity
                .get(uri)
                // ํ—ค๋” ์ถ”๊ฐ€
                .header("X-Naver-Client-Id", "Client-Id")
                .header("X-Naver-Client-Secret", "Client-Secret")
                .build();

        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);

        log.info("NAVER API Status Code : " + responseEntity.getStatusCode());

        return fromJSONtoItems(responseEntity.getBody());
    }

    public List<ItemDto> fromJSONtoItems(String responseEntity) {
        JSONObject jsonObject = new JSONObject(responseEntity);
        JSONArray items  = jsonObject.getJSONArray("items");
        List<ItemDto> itemDtoList = new ArrayList<>();

        for (Object item : items) {
            ItemDto itemDto = new ItemDto((JSONObject) item);
            itemDtoList.add(itemDto);
        }

        return itemDtoList;
    }
}

๊ฒฐ๊ณผ
Client ์ž…์žฅ์˜ Server ํ„ฐ๋ฏธ๋„

๏นก ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ๊ฐ€๊ณตํ•ด์„œ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ!