Introducing Micronaut Serialization: build-time optimizations for JSON

原文はこちら。
The original article was written by Graeme Rocher (Architect at Oracle Labs).
https://medium.com/graalvm/introducing-micronaut-serialization-build-time-optimizations-for-json-273f319525d9

Micronaut®フレームワークは、Micronaut Foundation¹に支えられたモダンなフルスタックフレームワークです。本日、GraalVMを使ったCloud Nativeアプリケーションの構築をさらに最適化する、Oracle Labsによる新たな大きな貢献である、Micronaut Serializationを発表します。Micronaut Serializationは、リフレクションを使わずにJavaの型(Java 17で導入されたRecordsを含む)をJSONや他のフォーマットとの間でシリアライズおよびデシリアライズできます。

Micronaut Foundation
https://micronaut.io/foundation/
Micronaut Serialization
https://micronaut-projects.github.io/micronaut-serialization/1.0.x/guide/#introduction

Background & Rationale

Micronautフレームワークは、最初のリリース以来、Jackson DatabindをデフォルトのJSONライブラリとして使用しており、今日も引き続き同様です。Jacksonは広く採用されている非常に柔軟なライブラリで、あらゆる形やサイズのJava型のシリアライズとデシリアライズに必要なあらゆるオプション機能を備えています。しかしながら、Jacksonにはいくつかの欠点があります。

  • Jacksonは、基本的にランタイム・リフレクションとアノテーションのランタイム解析の利用をベースにしています。このため、起動時間やメモリー消費に影響を与えるランタイム・インフラストラクチャが大量に発生します。
  • Jacksonでは、あらゆる型がシリアライズ可能であるため、潜在的な脆弱性に対する攻撃対象領域が大きくなります。
  • Jacksonのアノテーションベースのプログラミング・モデルは、ビルド時ではなく実行時にチェックされるため、開発者のエラーを発見するのが遅くなります。
  • Jacksonを多用するアプリケーションでは、Native Imageの追加設定が頻繁に必要になります。

Micronaut Serializationのリリースにより、ユーザーは、既存のJacksonアノテーションとほぼ互換性があり、以下のような多くの利点を備えた代替実装方式を選択できるようになりました。

  • Micronaut Serialization は、ビルド時に実行されるbean introspectionを使用するため、リフレクションの必要性が完全に排除されます。これは、GraalVM Native Imageに対して余分な構成をしなくて済むことを意味します。
  • アノテーションの使用は型チェック付きです。そのため、例えば@JsonFormatに無効な日付形式を指定すると、コンパイル時にエラーが発生します。これにより、生産性が大幅に向上します。
  • セキュリティの面では、明示的にシリアライズ可能、デシリアライズ可能と宣言された型のみが許可されます(ただし、ご自身でアノテーションできない型をインポートしたり、カスタムシリアライザ、デシリアライザを記述することはできます)。これにより、アプリケーションのセキュリティが大幅に向上します。
    Enabling Serialization of External Classes
    https://micronaut-projects.github.io/micronaut-serialization/1.0.x/guide/#serdeImport
    Custom Serializers & Deserializers
    https://micronaut-projects.github.io/micronaut-serialization/1.0.x/guide/#serdes
  • GraalVM Native Imageが解析するために必要なランタイムコードが削減されます。Jackson Databindは2.1MBのJARファイルであるのに対し、Micronaut Serializationはビルド時にのみ存在するロジックのため、わずか400KBにすぎません。この結果、ネイティブの実行ファイルサイズも3MB削減されます。
上図(GraalVM 22.0.0でテスト)は、Native Imageのビルド時間(秒)、ビルドイメージのサイズ(メガバイト)、アプリケーションへの最初のリクエスト後のメモリ占有量(メガバイト)を比較したもの

How it works

Micronaut Serializationは、Java annotation processingを使ってソースレベルのアノテーション(Jacksonアノテーション、JSON-Bアノテーション、BSONアノテーション)を解釈し、ビルド時にBean Introspectionsを使うシリアライザーやデシリアライザーを構築するため、リフレクションやアノテーションの広範囲にわたる実行時解析は必要ありません。

Bean Introspection
https://docs.micronaut.io/latest/guide/#introspection

【注意】
利用可能なJacksonアノテーションのサブセットはサポートされていますが、最も一般的なものはサポートされています。サポートされていないアノテーションを使用すると、コンパイルエラーが発生し、サポートされていないアノテーションが説明されます。
4 Jackson Annotations
https://micronaut-projects.github.io/micronaut-serialization/1.0.x/guide/#jacksonAnnotations

4 Jackson Annotations

そして、Micronaut Serializationを実行するパーサー/ジェネレーター・ランタイムを選択できます。初期リリースではJackson Core、JSON-P、BSONがサポートされています。

Getting Started

ドキュメントには、既存のMicronautアプリケーションでお好みのアノテーションベースのプログラミングモデルを使い始める方法についての素晴らしいクイックスタート手順が用意されています。

Quick Start
https://micronaut-projects.github.io/micronaut-serialization/1.0.x/guide/#quickStart

一般的に、Micronaut Serializationの使用は、追加のアノテーション・プロセッサの依存関係や、希望するランタイム実装の依存関係を追加するのと同じくらい簡単です。例えば、GradleビルドでJacksonコア(言い換えれば、databindを使用しないパーサーとジェネレーターのみ)を使用する場合には以下のような感じです。

dependencies {
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
implementation("io.micronaut.serde:micronaut-serde-jackson")
...
}
view raw build.gradle hosted with ❤ by GitHub

あとはPOJOやJava 17のRecordに対してJacksonアノテーションを付加するだけです。

package example;
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonClassDescription
public record Book(
String title,
@JsonProperty(defaultValue="10")
int pages) {
}
view raw Book.java hosted with ❤ by GitHub

Micronautフレームワークを使用している場合、Micronaut Serializationが自動的に統合され、RESTのレスポンスからKafka経由で送信されるメッセージに至るまで、フレームワーク全体でJSONのシリアライズとデシリアライズを処理できます。もし、プログラム的にオブジェクトのシリアライズやデシリアライズを行いたい場合は、JacksonのObjectMapperインターフェースに相当するものも利用でき、依存関係として注入できます。

Interface ObjectMapper
https://micronaut-projects.github.io/micronaut-serialization/1.0.x/api/io/micronaut/serde/ObjectMapper.html

Up Next: Micronaut Data for Document Databases

私たちは、Micronaut Data MongoDB(Oracle Autonomous DatabaseのMongoDB APIと統合する予定です)の開発にも力を入れており、このMicronaut Dataの実装をMicronaut Serializationをベースにして構築することに決めました。

Micronaut Data MongoDB
https://micronaut-projects.github.io/micronaut-data/snapshot/guide/#mongo

Micronaut SerializationがBSONと統合し、エンドツーエンドで使用できるようになるため、MongoDBアプリケーションを構築する際に、複数のJSONパーサー/ジェネレーター(例えば、Web層にはJackson、データベース層にはBSON)を使用する必要がなくなる、ということです。

Micronaut Serializationをエコシステム全体で使い、Native Imageに対応し、Micronautフレームワークの設計の根底にある、インテリジェントなコンパイラと小さく軽量なランタイムの哲学に沿ったアプリケーションを構築できることに非常に興奮しています。


¹ Micronaut®はObject Computing, Inc.の登録商標です。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中