3

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.

Jim Wharton
  • 1,375
  • 3
  • 18
  • 41

2 Answers2

4

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}").

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • Yep. Also `run { systemProperty('micronaut.environments','dev') }` was required in my `build.gradle`. Once I added that, I could use `@Client("\${myserviceclient.baseUri}")` (The backslash is required due to Kotlin's string interpolation). Thank you! – Jim Wharton Nov 29 '19 at 17:22
  • FYI... The system property isn't really required, that is one way to do it though. For example, you could also set the `MICRONAUT_ENVIRONMENTS` operating system environment variable and have the same effect. – Jeff Scott Brown Nov 29 '19 at 23:04
0

If you want the url somewhere in your code use this:

@Value("${micronaut.http.services.occupancy.urls}")
private String occupancyUrl;
tibi
  • 657
  • 1
  • 10
  • 22