๐Ÿง‘โ€๐Ÿ’ป [Spring Boot] Retrofit2๋กœ API ์—ฐ๋™ํ•˜๊ธฐ

J_m2nยท2024๋…„ 2์›” 23์ผ
0


ํฌ์ผ“๋ชฌ ๋„๊ฐ ๋งŒ๋“ค๊ธฐ ํ”„๋กœ์ ํŠธ

ํฌ์ผ“๋ชฌ API์˜ ์ฃผ์†Œ๋Š” "https://pokeapi.co/api/v2/" ์ด๋‹ค.
์ด ๋’ค์—๋Š” pokemon/{id}๋‚˜ pokemon-species/{id} ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์ถ”๊ฐ€์ ์ธ ์ฃผ์†Œ๋“ค์ด ์žˆ๋‹ค.
์ด๊ฑฐ๋Š” ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ผ์„œ ๊ณจ๋ผ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.


ํฌ์ผ“๋ชฌ API๋ฅผ ์—ฐ๋™ํ•˜๋ฉด์„œ Retrofit2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

Retrofit2๋ž€?

์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ(Android)์˜ HTTP ํ†ต์‹ ์„ ์œ„ํ•ด Square์‚ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋„คํŠธ์›Œํฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

Retrofit์œผ๋กœ API๋กœ response์™€ call์„ ๋ฐ›๊ธฐ ์œ„ํ•ด, ๊ทธ๋ฆฌ๊ณ  ์‘๋‹ต ๋ฐ์ดํ„ฐ ํ˜•์‹์„ JSON์œผ๋กœ ๋ฐ›๊ธฐ์œ„ํ•ด ์•„๋ž˜ ์ฝ”๋“œ๋“ค์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

๊ทธ๋ฆฌ๊ณ  Retrofit ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl) //API ๊ธฐ๋ณธ URL
                .addConverterFactory(GsonConverterFactory.create())
                .build();

๊ทธ๋ฆฌ๊ณ  Service ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ๊ผญ interface๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.
public interface PokeService{
	@GET(/pokemon/{no})
	public Call<PokemonVO> function(@Path("no") String no);
}

์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ƒ์„ธ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Retrofit ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•œ ๊ณณ์—์„œ VelogService ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

PokeService pokeService;
pokeService = retrofit.create(PokeService.class);

์ž‘์—…์„ ์ง„ํ–‰ํ•  ํ•จ์ˆ˜ ์•ˆ์— Call<>์„ ์ด์šฉํ•˜์—ฌ API๋กœ ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›์•„์˜จ๋‹ค.
์ฐธ๊ณ ๋กœ Call์€ ๋™๊ธฐ ๋ฐฉ์‹์ด๊ณ  Callback<>ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ๋ฐฉ์‹์ด๋‹ค.

Call<PokemonVO> call = pokeService.getspeciesData(no);
Response<PokemonVO> response = call.execute();

๊ทธ๋ฆฌ๊ณ  response์— json ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™”์œผ๋ฉด,

PokemonVO pokeVO = response.body();

๋กœ JSON ๋ฐ์ดํ„ฐ์˜ ํ•ต์‹ฌ ๋ถ€๋ถ„์ธ body()๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฑด PokemonVO ํด๋ž˜์Šค์ด๋‹ค.
JSON ๋ฐ์ดํ„ฐ์˜ Key๊ฐ’๊ณผ PokemonVO ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ์ด๋ฆ„์„ ๋˜‘๊ฐ™์ด ํ•ด์•ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ๋ฐ›์•„์™€์ง„๋‹ค.
ex) JSON ๋ฐ์ดํ„ฐ์— "name" ํ‚ค๊ฐ€ ์žˆ๋‹ค๋ฉด @SerializedName ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด์„œ ์ง์ ‘ ์ง€์ •ํ•ด์ฃผ๊ฑฐ๋‚˜, ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ ๋˜‘๊ฐ™์ด ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.

@SerializedName("name")
private String str;
private String name;

๋ฌด์กฐ๊ฑด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ!!

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ names[] ์ฒ˜๋Ÿผ ๋ฐฐ์—ด ํ˜•ํƒœ์˜ ํ‚ค๊ฐ’์ด ์žˆ๋‹ค๋ฉด

@SerializedName("names")
private List<NameInfo> names;

์ด๋ ‡๊ฒŒ ๋ฐฐ์—ด ํ˜•ํƒœ์˜ names ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

@Getter
public static class NameInfo{
    @SerializedName("name")
    private String name;
}

๊ทธ๋ฆฌ๊ณ  PokemonVO ํด๋ž˜์Šค ์•ˆ์— NameInfo ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“  ๋‹ค์Œ, names[] ํ‚ค๊ฐ’ ์•ˆ์— ์žˆ๋Š” ๊ฐ์ฒด์—์„œ ๋ฝ‘์•„์˜ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋˜ ๋˜‘๊ฐ™์ด ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.



๊ทธ๋ฆฌ๊ณ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ์ฒด๋“ค์— ์ ‘๊ทผํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๋œ๋‹ค!

List<PokemonVO.NameInfo> names = pokeVO.getNames();
PokemonVO.NameInfo nameInfo = names.get(2);
String name = nameInfo.getName();

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์ž์‹ ์—๊ฒŒ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋ฝ‘์•„์˜ค๋ฉด ๋จ!!





JSON ๋ฐ์ดํ„ฐ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ


Pokemon.java ํด๋ž˜์Šค
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Pokemon {
    private int no;
    private String korean;
    private String img;
    private String simg;
    private String[] types = new String[2];
    private ArrayList<Ability> abilities;
    private String genus;

    @Getter
    @AllArgsConstructor
    public static class Ability{
        String name;
        String hidden;
    }
}

๋‚ด๊ฐ€ ๋งŒ๋“ค๊ณ  ์‹ถ์€ ๋ฐ์ดํ„ฐ ํ˜•์‹์€ ๊ฐ ํฌ์ผ“๋ชฌ ๋งˆ๋‹ค ๊ทธ ํฌ์ผ“๋ชฌ ๋งŒ์˜ ์ •๋ณด๋ฅผ ๋‹ค ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.


์ฒ˜์Œ์— ๋™๊ธฐ ํ†ต์‹ ์„ ์‚ฌ์šฉํ•˜๋‹ˆ๊นŒ 1024๋งˆ๋ฆฌ์˜ ํฌ์ผ“๋ชฌ๋“ค์˜ ์ •๋ณด๋ฅผ ํ•˜๋‚˜ ํ•˜๋‚˜์”ฉ ๊ฐ€์ ธ์™€์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—„์ฒญ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค.
๊ทธ๋ž˜์„œ ๋น„๋™๊ธฐ ํ†ต์‹ ์œผ๋กœ๋„ ํ•ด๋ณด๊ณ  ํ–ˆ๋Š”๋ฐ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋“ค์€ api ์ฃผ์†Œ๋“ค์ด ๋‹ค ๋‹ฌ๋ผ์„œ ๊ฐ๊ฐ ๋”ฐ๋กœ๋”ฐ๋กœ ๋ฝ‘์•„์™€์•ผ ํ•ด์„œ ๋ฐ์ดํ„ฐ๋“ค์ด ๋’ค์ฃฝ๋ฐ•์ฃฝ์ด ๋˜๋Š” ๊ฒƒ,,

๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ JS์—์„œ Promise๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์‹œ๋Š” ๋ถ„๋“ค๋„ ์žˆ์—ˆ๋Š”๋ฐ, ์ด๋ฏธ ์ปจํŠธ๋กค๋Ÿฌ๋‚˜ DAO๋‚˜ VO ๊ฐ™์€ ๊ฑธ ๋‹ค ์„ค์ •ํ•ด๋†“์€ ์ƒํƒœ๋ผ JS์—์„œ API๋กœ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์ง€ ์•Š์•˜๋‹ค.

๊ทธ๋ ‡๋‹ค๊ณ  ๊ทธ๋Œ€๋กœ API๋ฅผ ์‚ฌ์šฉํ•˜์ž๋‹ˆ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ๋งŒ 25๋ถ„ ์ •๋„ ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค..(์ด๊ฑด ๋‚ด๊ฐ€ ์ข€ ์‹ค์ˆ˜ํ•ด์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ผฌ์—ฌ์„œ ์—„์ฒญ ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๊ฑฐ์˜€์Œ..!)


๋„์ €ํžˆ ์•ˆ๋˜๊ฒ ๋‹ค ์‹ถ์–ด์„œ ์ƒ๊ฐํ•ด๋‚ธ๊ฒŒ JSON ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ api ๋ง๊ณ  ๊ทธ ํŒŒ์ผ์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด ์ข€ ๋” ๋นจ๋ผ์ง€์ง€ ์•Š์„๊นŒ?! ์‹ถ์—ˆ๋‹ค.


๊ทธ๋ž˜์„œ JSON ํŒŒ์ผ์— ๋„ฃ์„ ๋ฐ์ดํ„ฐ๋ฅผ api๋กœ ๋‹ค ๊ฐ€์ ธ์™€์„œ JSON ํŒŒ์ผ๋กœ ์ €์žฅ์‹œ์ผฐ๋‹ค.

JSON ํŒŒ์ผ ์ƒ์„ฑํ•˜๋Š” ๋ฒ•

ArrayList<Pokemon> allPokemons = pokeDAO.allList(1,1010);
ObjectMapper mapper = new ObjectMapper();
     try {
         // JSON ํŒŒ์ผ๋กœ ์“ฐ๊ธฐ
         mapper.writeValue(new File("data.json"), allPokemons);
         System.out.println("JSON ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
     } catch (Exception e) {
         e.printStackTrace();
     }

ArrayList ํ˜•ํƒœ์˜ ๊ฐ์ฒด๋ฅผ JSON ๋ฐ์ดํ„ฐ๋กœ ์•Œ์•„์„œ ๋งŒ๋“ค์–ด์ค€๋‹ค!
JSON ํŒŒ์ผ๋„ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ ์ด์ œ ์ด ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฝ‘์•„์™€ ๋ด์•ผ์ง•~~

profile
์ฝ”๋”ฉ ์ดˆ์งœ์ž…๋‹ˆ๋‹ค

0๊ฐœ์˜ ๋Œ“๊ธ€