SpringBootとSendGridでまたハマった

技術ネタ
この記事は約6分で読めます。

こんばんわ、hisayukiです。

なんか、このネタ以前もハマった気がするんですけど・・・
その時の記録がないので今回はちゃんと記録しておきますw

スポンサーリンク

SendGridはAutoConfigure対応

SpringBootのAutoConfigureで
SendGridを初期化してDI出来るようになる。

今回大事なのはこれだけ。

具体的にはapplication.ymlspring.sendgrid.api-keyにAPIKeyを書いておく。

spring:
  application:
    name: sample

  sendgrid:
    api-key: ${SENDGRID_SECRET_API_KEY}

上のソースコードは普段は環境変数にSENDGRID_SECRET_API_KEYを設定して取得してるので、そのままの書き方してます。
あとは以下のようにAutowiredでSendGridクラスがとれるようになります。

import com.sendgrid.Mail
import com.sendgrid.Method
import com.sendgrid.Request
import com.sendgrid.Response
import com.sendgrid.SendGrid
import org.springframework.beans.factory.annotation.Autowired
import java.io.IOException

class SendGridApplicationService (
    @Autowired
    private var sendGrid: SendGrid
) { 
    fun sendMail(mail: Mail): Response =
        try {
            mail.setTemplateId("*********************")
            queryModel(response =
                sendGrid.api(
                    Request().apply {
                        method = Method.POST
                        endpoint = "mail/send"
                        body = mail.build()
                    }
                )
            )
        } catch (ex: IOException) {
            throw ex
        }
}

SpringBootのGithubを見ていただくとソースコードがあります。

spring-projects/spring-boot
Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.

AutoConfigureとは?

ざっくり言うとAnnotation付与で起動時に自動でDIコンテナとして使えるようにしてくれる機能です。
SpringBootのメイン機能ですね、具体的な説明は省きますがこちらの記事がわかりやすいです。

Spring BootのAutoConfigureの仕組みを理解する - Qiita
今回は、Spring Bootのメイン機能の一つであるAutoConfigureの仕組みを紹介したいと思います。 Spring Bootを利用すると、簡単なアプリケーションであれば開発者がBean定義を行わなくてもSpringアプリケ...

何にハマったか

ymlの書き方を変えたら動かなくなりましたwww

なんでSendGridのapiKeyがymlのSpringの下にあるのか忘れちゃったんですよね・・・

SaaSのsendgridspringの下にあるのおかしくね?ってなって同じ階層にしました。

spring:
  application:
    name: sample

  
sendgrid:
  api-key: ${SENDGRID_SECRET_API_KEY}

ここで、動かなくなりハマりました・・・・

実際はここをいじった後にあちこち触ってからテストを走らせた時に気づいた感じです。

解決方法

こちら実際のSpringBootのSendGridAutoConfigurationのソース

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(SendGrid.class)
@ConditionalOnProperty(prefix = "spring.sendgrid", value = "api-key")
@EnableConfigurationProperties(SendGridProperties.class)
public class SendGridAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(SendGridAPI.class)
	public SendGrid sendGrid(SendGridProperties properties) {
		if (properties.isProxyConfigured()) {
			HttpHost proxy = new HttpHost(properties.getProxy().getHost(), properties.getProxy().getPort());
			return new SendGrid(properties.getApiKey(), new Client(HttpClientBuilder.create().setProxy(proxy).build()));
		}
		return new SendGrid(properties.getApiKey());
	}

}

@ConditionalOnProperty(prefix = "spring.sendgrid", value = "api-key")

ちゃんとAutoConfigureはspring直下のsendgrid.api-keyを見てますね。
なので初期化されたSendGridクラスがDIコンテナとして作成されなくなります・・・

上に乗せたソースコードの@Autowiredが動かなくなります。

class SendGridApplicationService (
    @Autowired
    private var sendGrid: SendGrid
) { 

そりゃ動かないわ・・・

おとなしくymlを元に戻しました。

まとめ

まず、一回ハマったことはちゃんと残さないとですね。

前にも疑問に思って調べた気がするんですよね・・・・
また同じこと調べて1時間以上費やした気がする・・・

Gitで動いたところまで戻せばよかったんですが、今回こまめにcommitしてなかったので結構な手戻りになるのが嫌で・・・w
こちらももう少しこまめにcommitする習慣必要ですね(;´∀`)

ただ、AutoConfigureの機能を再度調べる機会にもなったので、得られるものはあったかなと。
今回は記載しませんが、AutoConfigureについてもまたそのうち書こうと思います。

コメント