mike-neckのブログ

Java or Groovy or Swift or Golang

Groovy が書けない人のための Gradle 入門

若干ネタ気味ですが、 Groovy を覚えるのが面倒だけど、 Kotlin を覚えるのも面倒という方のためにお勧めしたいのが、 Java で書くという方法です。

f:id:mike_neck:20190619163018p:plain

というわけで、次のような build.gradle を書きます。

Project project = getProject();

project.getPluginManager().apply("java-library");

project.setGroup("org.example");
project.setVersion("1");

project.setSourceCompatibility(JavaVersion.VERSION_11);
project.setTargetCompatibility(JavaVersion.VERSION_11);

project.getRepositories().mavenCentral();

project.getDependencies().add("implementation", "org.slf4j:slf4j-api:1.7.25");
project.getDependencies().add("testImplementation", "org.junit.jupiter:junit-jupiter:5.4.2");

project.getTasks().<Test>named("test", Test.class, new Action<Test>() { @Override public void execute(Test test) { test.useJUnitPlatform(); }  });

では、ビルドを走らせてみましょう

f:id:mike_neck:20190629120614p:plain

見事ビルドできたようです。


Groovy は Java なので、 Groovy がわからないと焦る前に、 Java で書いてしまえばよいです

ただ、一つだけ注意点があって、Gradle が使っている Groovy のバージョンが 2.5.x のため、 Java8 の lambda のような記述を解釈できないので、 Actionインスタンスに対しては匿名クラスで対応せざるを得ないことです。

Functional Spring Hands On に行ってきた

表題の通り、 Functional Spring Hands On に行ってきた。

pivotal-japan.connpass.com

ハンズオンの資料はこれ

github.com

基本的に手を動かさないと理解が遅いので、わりとハンズオンは好きです(用意する方は大変)

内容は、 Spring(WebFlux) アプリケーションを @SpringBootApplication なしで記述するというもの。さらに R2DBC もついてた。

R2DBC はまだ開発が進んでいる最中で、以前のエントリーは完全に無意味になってた…

続きを読む

Mono<Void> は常に empty

当然といえば当然ですが、意外と気づかない。

例えば、特定の条件を満たさないとリクエストを処理しないような WebFilter を記述する。

@Bean
WebFilter webFilter() {
  return (exchange, chain) -> {
    Optional<String> requestDate = extractRequestDate(exchange);
    return Mono.justOrEmpty(requestDate)
        .flatMap(date -> Mono.defer(() -> chain.filter(exchange)))
        .switchIfEmpty(() -> forbidden(exchange));
  };
}

このような感じで何らかのヘッダーの値がある場合は処理を行った結果を返すが、ない場合は 403 Forbidden を返すみたいな WebFilter を書いたのだが、 これは常に 403 Forbidden を返し続ける。

WebFilterChain#filter(ServerWebExchange)Mono<Void> を返すが、タイトルにあるように Mono<Void> は(Voidインスタンスが作れないため)常に empty になる

ここでは、 Mono を連鎖させるのではなく、 Optional の値によって取り回すほうがよい

@Bean
WebFilter webFilter() {
  return (exchange, chain) -> {
    Optional<String> requestDate = extractRequestDate(exchange);
    return requestDate
        .map(date -> Mono.defer(() -> chain.filter(exchange)))
        .orElseGet(() -> forbidden(exchange));
  };
}

resilience4j の RateLimiter を少しだけいじった

resilience4j の RateLimiter を少しだけいじったので、そのメモ。 ここの実装はダメな実装になってるので、ちゃんとした使い方を調べてる人は他をあたった方が良い(強く推奨)。

続きを読む