Vert.x入坑注意(3)


Vert.に従ってxは3.5.0に進化し、本シリーズも新たな章を迎えた.
CORSの新しい変化
CORSについては、Web開発(フロントエンドでもバックエンドでも)を行う同志はよく知られていないはずです.特に、今のマイクロサービスが盛んな時代には、CORSは最もよく使われる配置項目の一つです.もしあなたがこれに対してまだ少し疑問があるならば、聞く必要はありません.あなたはもう時代遅れです.
Vert.xは早くからCORSをサポートしていたが、3.5.0になると、セキュリティ上の考慮から制限が追加された.
allowedOriginPatternが「*」の場合、allowCredentialsは「true」を許可しません.
この制限は、プロトコルの制限から始まっています.
The string "*"cannot be used for a resource that supports credentials.The string "* "cannot be used for a resource that supports credentials.
すなわち、Access-Clontrol-Allow-Originが「*」の場合、Access-Clontrol-Allow-CRedentialsは無視され、Credentials情報(一般的にCookie)もuser-agentによって送信されない.この文章(英語原版)を参考にして、各ヘッダーを安全に設定する方法を知ることができます.
3.5.0でallowedOriginPatternが「*」、allowCredentialsが「true」の場合、Vert.xに異常が発生し、処理しないとVerticleが正常に起動しません.以前のバージョンでは、このような状況は発生しませんでした.
CB for handler
遮断器は良いもので、不注意な開発者が書いたコードが他の良いコードを乱すことを避けるために、フレームワーク設計でそれを考慮することを強くお勧めします.私がdgateとdfxを書いたとき、すべての対外暴露サービスにもこの制限を強要しました.
CBがこんなに良い以上、普通のHandlerに適用する考えを働かしたのではないでしょうか.でもVert.xCBの文書例では,すべてクリアなHTTPリクエストの例が示されているが,CBを一般のHandlerに広く適用するには少し手間がかかる.
dfxにツールクラスを書き、このニーズをカプセル化しました.
public static void withCircuitBreaker(Vertx vertx, CircuitBreaker circuitBreaker
        , Accessible accessible, Map params, Handler successHandler, Handler failureHandler) {
    circuitBreaker.execute(future ->
            vertx.executeBlocking(f -> {
                        try {
                            f.complete(accessible.invoke(params));
                        } catch (Throwable throwable) {
                            f.fail(throwable);
                        }
                    }
                    , result -> {
                        if (result.succeeded()) {
                            future.complete(result.result());
                        } else {
                            future.fail(result.cause());
                        }
                    })
    ).setHandler(result -> {
        if (result.succeeded()) {
            successHandler.handle((Map) result.result());
        } else {
            logger.error("CB[{}] execution failed, cause: ", circuitBreaker.name(), result.cause());
            failureHandler.handle(result.cause());
        }
    });
}

その使用は簡単です.
Utils.withCircuitBreaker(vertx, circuitBreaker, accessible, body.getMap()
               , result -> Utils.fireJsonResponse(response, 200, result)
               , throwable -> Utils.fireSingleMessageResponse(response, 500, throwable.getMessage()));

皆さんはひょうたんでひょうたんを描くことによって自分の形式に変えることができて、その中の重点は“vertx.executeBlocking”の方式でHandlerのコードを実行することにあります.
テスト
少し正規のチームでは、自動化テストはすでに標準的な実践であるべきであり、Vert.xはテストにもサポートされています.
でも、私は好きではありません.理由はいくつかあります.
  • Vert.x UnitはJUnitに基づいていますが、私はすでに好きなテストフレームワークを持っています:Spock.JUnitと比べると、後者はJavaテスト分野の戦闘機と言える.
  • の良いユニットテストは本来、使用するフレームワークにできるだけ依存しないようにしなければならないことに注意した後、クラスをよくテストするように設計した結果、普通のユニットテストクラスが作成された.さわやかな道具がある以上、Vert.を使う必要はありません.x Unitです.
  • 統合テストでは、実際の環境を直接シミュレートし、適切なtimerを加えることで、現在のところ悪くないようです.そしてVert.x Unitでも同様にtimerを使う必要があります.そうすれば、わざわざ使う必要はありません.

  • 私の言ったことが虚しくないことを証明するために、dgateとdfxのテストコードを見てみましょう.ここでは2つの例を示します.
  • 統合テスト
  • ユニットテスト
  • いずれもSpockに基づいて書かれており、酸っぱさを体験することができます.
    実行時外部構成
    本シリーズの第1編では、気に入ったエンジニアリング構造の構成を提案しましたが、「ランタイム外部プロファイル」という一般的な実践には言及していません.
    いくつかのプロジェクトの鍛錬を経て、現在、このような実行時の外部プロファイルに対して、私は基本的に1つの固定セットを形成しました:Groovy DSL+Groovy ConfigSlurper.Vert.と比べるとxの提供するjsonプロファイルは爽やかすぎます.
    Gradleのbuildファイルを見てみると、このDSLの柔軟性がどの程度可能かを知ることができます.ましてGroovyの文法はJava開発者にとって極めて友好的です.
    Groovyはクールではなく、Scala、Clojure、Kotlin、Go、Rustと呼ぶ必要があると軽蔑する人もいるかもしれません.これに対して、兄は「開発者として、最も軽蔑されているのは仕事ができないことだ.お客様はあなたがどんな言語を使うか気にしない」と言いたいだけだ.
    DSLの構成例:dgate構成
    dgateは私が書いたvertxベースの軽量レベルのゲートウェイで、すべての構成はすべてプロファイルによって定義され、データベースは必要ありません.詳細については、ドキュメントを参照してください.前節でGroovy DSLを用いた柔軟性を説明するために,ここではいくつかのdgateの構成例を示す.
    静的ロック
    dgateのmock機能を利用して、分離した前後端の開発者は並列に仕事をすることができて、mock応答をdgateのプロファイルに配置するだけでいいです.
    "/summary" {
        expected {
            statusCode = 200
            payload {
                eqLocations = []
                opRateInLast30Days = []
                myOrgs = [
                    ["name": "org1", "admin": false]
                ]
            }
        }
    }

    ダイナミックロック
    動的Mockは、動的結果(場合によっては成功、場合によっては失敗)を返すURLシミュレーションに便利です.
    "/login" {
        required = ["sub", "password"]
        methods = [HttpMethod.GET, HttpMethod.POST]
        expected {
            statusCode = 200
            payload = {
                JWTAuth jwtAuth = Utils.createAuthProvider(Vertx.vertx())
                JWTTokenGenerator tokenGenerator = new JWTTokenGenerator(jwtAuth)
                [token: tokenGenerator.token(["sub": "……", "name": "……", "role": "normal"], 200)]
            }
        }
    }

    上記の例では、フロントエンド/モバイルエンドの開発を容易にし、このシーンに対して他の特別な処理を必要とせずに、実際のダイナミックJWTをシミュレートします.
    動的結果を生成するために、ここでpayloadは、前の例ではMapではなく閉パッケージを使用していることに注意してください.このとき,閉パケットの戻り値はMock応答の結果となる.
    以上の例ではGroovy DSLを実行時外部構成とする能力を十分に示しており,完勝Vertといえる.x独自のjson構成方式.
    さて、今期の内容はこれで終わりますので、ご注目ください.
    このシリーズのその他の記事:
  • Vert.x入坑注意(1)
  • Vert.xピット注意(2)