본문 바로가기

[TIL][내일배움캠프]

[내일배움캠프][TIL] 24.02.08 (목) - 팀 프로젝트(심화) : 네이버 백과사전 API 연결

1. 팀 프로젝트(심화)

 

어제는 상세 화면의 UI에 대한 전반적인 부분들을 만들었다.

 

오늘은 아직 미완성된 부분들을 완성시킬까 하다가 더 급한 부분부터 완성시키기로 하였다.

그것이 무엇인고 하니 바로 네이버 백과사전 API 되시겠다.

 

 

네이버 백과사전 API

 

미디어 앱을 만든다면서 뜬금없이 네이버 백과사전 API가 왜 튀어나오냐 할 수 있지만, 이 부분 때문에 필요하다.

 

동물 카테고리를 클릭하면 이렇게 그 동물과 관련된 영상과 더불어 백과사전에 나오는 정보가 뜨도록 했는데 이 때 저 백과사전 정보에 네이버 백과사전 API를 이용할 생각이다.

 

 

그렇다면, 네이버 API는 어떻게 구성되어 있는지부터 살펴보자.

 

우선은은 요청할 때 필요한 요소들이다.

여기 보면 요청 URL에  https://openapi.naver.com/v1/search/encyc.json 으로 적혀 있는데 참고사항에 보면 GET에 v1/search/encyc를 적으라고 되어 있으므로 Base url은 https://openapi.naver.com 이 되겠다.

 

그리고 특이하게도 네이버는 헤더에 Naver-Client-Id와 Naver-Client-Secret 이 두가지를 넣어야 한다.

또한 요청 예를 잘 보면 -H 뒤에 "X-Naver-Client-Id"로 되어 있는데 이 풀네임을 헤더에 집어넣어야 한다.

  • @Header(" X-Naver-Client-Id")
  • @Header(" X-Naver-Client-Secret")

마지막으로, 인터페이스에 요청할 때 query는 필수적으로 들어가야 하고, display, start는 선택적으로 넣을 수 있다.

 

 

다음은 요청한 뒤에 응답받는 요소들이다.

rss 안에 channel이 있고, 그 channel 안에 lastBuildDate, total, start, display, items가 있으며, items 안에 title, link, description, thumbnail이 있는 구조다.

 

이를 바탕으로 코드로 나타내어봤다.

 

NaverAPI.kt

interface NaverAPI {
    @GET("v1/search/encyc.json")

    suspend fun naverDic(
        @Header("X-Naver-Client-Id") Id: String?,
        @Header("X-Naver-Client-Secret") Secret: String?,
        @Query("query") query: String
    ): Call<NaverData>
}

 

NaverData.kt

data class NaverData(
    @SerializedName("channel")
    val channel: ArrayList<Channel>
)

data class Channel(
    @SerializedName("last_build_date")
    val lastBuildDate: String,

    @SerializedName("total")
    val total: Int,

    @SerializedName("start")
    val start: Int,

    @SerializedName("display")
    val display: Int,

    @SerializedName("item")
    val item: ArrayList<Items>
)

data class Items(
    @SerializedName("title")
    val title: String,

    @SerializedName("link")
    val link: String,

    @SerializedName("description")
    val description: String,

    @SerializedName("naverthumbnail")
    val thumbnail: String
)

 

NaverRetrofit.kt

object NaverRetrofit {

    val naverApiService: NaverAPI
        get() = instance.create(NaverAPI::class.java)

    private val instance: Retrofit
        private get() {
            val gson = GsonBuilder().setLenient().create()

            return Retrofit.Builder()
                .baseUrl(Constants.NAVER_BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build()
        }
}

 

그런데 여기서 약간 헷갈리는 부분은 바로 data class를 담당하는 NaverData.kt인데 channel부터 들어가는 건 쉬운데 앞에 rss와 channel은 타입이 없어서 이걸 안 적어도 되는 건지 적어야 하는 건지를 모르겠다. 나중에 집어넣어보면 알 수 있겠지.

 

 

우선은 아직 검색 결과 UI가 완성이 되지 않아서 여기까지만 작업을 해놓았다.

저게 완성이 되어야 query를 집어넣어서 적용시킬 수 있을 것 같다.

 

내친 김에 응답을 요청하는 함수도 미리 만들어볼까?

 

    private suspend fun fenchNaverResult(query: String) {
        NaverRetrofit.naverApiService.naverDic(Constants.NAVER_CLIENT_ID, Constants.NAVER_CLIENT_SECRET, query)
            ?.enqueue(object: Callback<NaverData> {
                override fun onResponse(call: Call<NaverData>, response: Response<NaverData>) {
                    val body = response.body()

                    body?.let {
                        response.body()!!.{
                            // 여기에 Adapter 연결하면 될듯
                        }
                    }

                    adapter.item
                    adapter.notifyDataSetChanged()
                    Log.d("네이버api 검사", "응답")
                }

                override fun onFailure(call: Call<NaverData>, t: Throwable) {
                    Log.d("네이버api 검사", "응답실패")
                }
            })
    }
}

 

뼈대만 이렇게 만들어놓고 나중에 완성되었을 때 덧붙이기만 하면 딱 되겠다.

 

 

내일부터는 설 연휴인데 아마도 설 연휴에도 프로젝트를 진행하지 않을까싶다. 꽤나 방대한 양이라서 말이….