Search code examples
kotlinmicronautmicronaut-client

Micronaut declarative client with base url per environment


I'd like to be able to use Micronaut's declarative client to hit an a different endpoint based on whether I'm in a local development environment vs a production environment.

I'm setting my client's base uri in application.dev.yml:

myserviceclient:
  baseUri: http://localhost:1080/endpoint

Reading the docs from Micronaut, they have the developer jumping through quite a few hoops to get a dynamic value piped into the actual client. They're actually quite confusing. So I've created a configuration like this:

@ConfigurationProperties(PREFIX)
class MyServiceClientConfig {

  companion object {
    const val PREFIX = "myserviceclient"
    const val BASE_URL = "http://localhost:1080/endpoint"
  }

  var baseUri: String? = null

  fun toMap(): MutableMap<String, Any> {
    val m = HashMap<String, Any>()
    if (baseUri != null) {
      m["baseUri"] = baseUri!!
    }

    return m
  }
}

But as you can see, that's not actually reading any values from application.yml, it's simply setting a const value as a static on the class. I'd like that BASE_URL value to be dynamic based on which environment I'm in.

To use this class, I've created a declarative client like this:

@Client(MyServiceClientConfig.BASE_URL)
interface MyServiceClient {

  @Post("/user/kfc")
  @Produces("application/json")
  fun sendUserKfc(transactionDto: TransactionDto)
}

The docs show an example where they're interpolating values from the config map that's built like this:

@Get("/api/\${bintray.apiversion}/repos/\${bintray.organization}/\${bintray.repository}/packages") 

But how would I make this work in the @Client() annotation?

Nowhere in that example do they show how bintray is getting defined/injected/etc. This appears to be the same syntax that's used with the @Value() annotation. I've tried using that as well, but every value I try to use ends up being null.

This is very frustrating, but I'm sure I'm missing a key piece that will make this all work.


Solution

  • I'm setting my client's base uri in application.dev.yml

    You probably want application-dev.yml.

    But how would I make this work in the @Client() annotation?

    You can put a config key in the @Client value using something like @Client("${myserviceclient.baseUri}").