背景
言語にKotlin, フレームワークにSpring boot(Gradle)を使用したAPIで、外部のAPIをコールする必要があったので。
以下にコードを載せてあるので必要な場合はぜひ。
https://github.com/shuichiro0926/kotlin_api_call
Jackson import
外部APIをコールした際のレスポンスが**Json(String)**の時、オブジェクトクラスにマッピングしてあげる必要があります。
Json(String) → Object(Model)クラス
以下をbuild.gradle
に記述してください。
(他のビルドツール使ってる方は調べてみてください。)
/* jackson */
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.0")
Rest template
外部APIをCallする処理にはSpring bootのRest templateを使用します。
getForObject, postForObject, exchangeメソッドがありますが、
先の2つはHttpHeaderを指定できないので今回はexchangeを使用します。
class ApiCall(
private val restTemplate: RestTemplate
) {
// 定数定義
companion object {
const val contentType = "Content-Type"
const val contentTypeValue = "application/json"
}
/**
* 外部API リクエスト.
*/
fun exchange(builder: UriComponentsBuilder, httpMethod: HttpMethod, entity: HttpEntity<Any>): String? {
// exchangeメソッドを使用。
val response: ResponseEntity<String> = restTemplate().exchange(
builder.toUriString(),
httpMethod,
entity,
String::class.java
)
return response.body
}
RestTemplateは@Beanとして以下のように定義してください。
WebConfigは複数のBeanを管理する設定クラスです。名前は変えてもらって大丈夫です。
@Configurationや@Beanが分からないという方はDIコンテナなど一緒にこちらの記事を読んでみると良いかもしれないです。
@Configuration
class WebConfig {
@Bean
fun restTemplate(): RestTemplate {
return RestTemplate()
}
}
Sample Call method
以下のようなコードで上記のメソッドを呼び出します。
APIをコールした結果(Json)は、最初にプロジェクトに入れたJacksonのjacksonObjectMapperでオブジェクトクラスに変換します。
/**
* Sample Api Call method
*/
fun doApiCall(): SampleDto {
// URI作成
val builder: UriComponentsBuilder = UriComponentsBuilder
.fromHttpUrl("")
.queryParam("", "")
// HttpHeader
val headers: HttpHeaders = HttpHeaders()
headers.set(contentType, contentTypeValue)
val entity: HttpEntity<Any> = HttpEntity(headers)
// call
val response: String? = exchange(builder, HttpMethod.GET, entity)
// Json → Object 変換
return jacksonObjectMapper().readValue(response, SampleDto::class.java)
}
SampleDtoは以下のような感じで。
/**
* JsonObjectMapper クラス.
*/
class SampleDto (
@JsonProperty("sampleId")
val sampleId: Int,
@JsonProperty("sampleName")
val sampleName: String,
@JsonProperty("createDate")
val createDate: Date?,
@JsonProperty("updateDate")
val updateDate: Date?
)
課題
ケースにもよると思いますが、もう少し汎用的に書けるのかもしれないです。
このような共通処理定義が必要になることは多々あると思います。