kotlinx.serialization は、Kotlin 公式の JSON 変換ライブラリです。 クラスに @Serializable を付け、Json.encodeToString(値) で JSON 文字列に、Json.decodeFromString<型>(文字列) でオブジェクトに戻します。リフレクション(実行時に型を調べるしくみ)を使わず、コンパイラプラグインが変換コードを作ります。

@Serializable
data class User(val id: Long, val name: String, val email: String? = null)

val json = Json.encodeToString(User(1, "Ito"))        // {"id":1,"name":"Ito"}
val user = Json.decodeFromString<User>(json)          // User(id=1, name=Ito, email=null)
やりたいこと 書き方
知らないキーを無視する Json { ignoreUnknownKeys = true }
既定値のプロパティも出力する Json { encodeDefaults = true }
null のプロパティを出力しない Json { explicitNulls = false }
整形して出力する Json { prettyPrint = true }
JSON のキー名を変える @SerialName("user_id")
JSON に出さない @Transient(既定値が必須)
snake_case に一括変換 Json { namingStrategy = JsonNamingStrategy.SnakeCase }
日付 kotlinx-datetime の LocalDate、または自作の KSerializer

確認環境:kotlinx.serialization 1.11.0(GitHub の CHANGELOG で最新の安定版。2026年4月10日公開)と kotlinx-datetime 0.8.0 を、GitHub のソース(タグ v1.11.0・v0.8.0)から Kotlin コンパイラ kotlinc 2.4.20 で JVM 向けにビルドし、同梱のシリアライズ用コンパイラプラグインと組み合わせて、OpenJDK 21.0.10・Linux で実行しました。本文の出力とエラー文は、この実行で得たものです。依存の書き方は kotlinlang.org のドキュメントで確かめました(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「kotlinx.serialization使い方|JSON変換・設定一覧・エラー」

依存の書き方

「コンパイラプラグイン」と「ライブラリ」の2つが必要です。 片方だけでは動きません。

// build.gradle.kts
plugins {
    kotlin("jvm") version "2.4.21"
    kotlin("plugin.serialization") version "2.4.21"   // Kotlin と同じ版
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")
}
入れるもの 役割 版の決め方
kotlin("plugin.serialization") @Serializable のクラスに変換コードを作る Kotlin と同じ版
kotlinx-serialization-json JSON の読み書き。core(共通部分)も一緒に入る ライブラリの版(1.11.0)

Maven では kotlin-maven-plugin の <compilerPlugins> に kotlinx-serialization を書き、プラグインの依存に org.jetbrains.kotlin:kotlin-maven-serialization を足します(kotlinlang.org の例)。Version Catalog で書く方法は、関連記事「build.gradle.kts書き方|Groovy対応表とバージョンカタログ」で扱っています。

プラグインを入れ忘れると

プラグインなしでコンパイルすると、コンパイルは通り、実行したときに次の例外になりました。

kotlinx.serialization.SerializationException: Serializer for class 'P' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.

@Serializable を付けたのにこのエラーが出るときは、まずプラグインを確かめます。

基本:encodeToString と decodeFromString

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString

@Serializable
data class User(
    val id: Long,
    val name: String,
    val email: String? = null,
    val tags: List<String> = emptyList(),
)

fun main() {
    println(Json.encodeToString(User(1, "Ito")))
    println(Json.decodeFromString<User>("""{"id":2,"name":"Sato","email":"s@example.com","tags":["a"]}"""))
    println(Json.encodeToString(listOf(User(1, "A"), User(2, "B"))))
    println(Json.decodeFromString<Map<String, Int>>("""{"a":1,"b":2}"""))
}
{"id":1,"name":"Ito"}
User(id=2, name=Sato, email=s@example.com, tags=[a])
[{"id":1,"name":"A"},{"id":2,"name":"B"}]
{a=1, b=2}

既定値と同じ値のプロパティ(email = null・tags = [])は、出力されません。 これが kotlinx.serialization の既定の動きです(encodeDefaults = false)。List・Map・Set などのコレクションは、そのまま変換できます。

Json のインスタンスは使い回す

Json { … } を関数の中で毎回作るコードをコンパイルすると、プラグインが次の警告を出しました。

warning: redundant creation of Json format. Creating instances for each use can be slow.

設定済みの Json は、トップレベルの val などに1つ作って使い回します。

val AppJson = Json {
    ignoreUnknownKeys = true
    explicitNulls = false
}

注釈:@SerialName・@Transient・@Required・@EncodeDefault

@Serializable
data class Article(
    @SerialName("article_id") val id: Long,
    val title: String,
    @Transient val cache: String = "not serialized",
    val status: Status = Status.DRAFT,
    @EncodeDefault val version: Int = 1,
    @Required val lang: String = "ja",
)

@Serializable
enum class Status {
    @SerialName("draft") DRAFT,
    @SerialName("published") PUBLISHED,
}
Json.encodeToString(Article(10, "Hello"))
{"article_id":10,"title":"Hello","version":1,"lang":"ja"}

Json { encodeDefaults = true }.encodeToString(Article(10, "Hello"))
{"article_id":10,"title":"Hello","status":"draft","version":1,"lang":"ja"}
注釈 意味 実行で確かめたこと
@Serializable 変換の対象にする 付けないと Serializer for class … is not found
@SerialName("x") JSON でのキー名・enum の値・sealed の型名 id が article_id で出た
@Transient JSON に出さず、読みもしない。既定値が必須 cache は出力されなかった
@EncodeDefault 既定値でも必ず出力する version は encodeDefaults = false でも出た
@Required 既定値があっても、読むとき JSON に必須 lang が無い JSON は MissingFieldException
@JsonNames("a", "b") 読むときだけ別名も受け付ける(実験的 API) user_name・login のどちらでも読めた
@JsonIgnoreUnknownKeys このクラスだけ知らないキーを無視(実験的 API) {"id":1,"extra":true} が読めた

@Transient は kotlinx.serialization.Transient です。JVM の kotlin.jvm.Transient(Java の transient 修飾子)とは別のものなので、import を確かめます。

既定値の無いプロパティは、JSON に必須です。 既定値があるプロパティは、JSON に無ければ既定値になります。この「既定値があるかどうか」が、MissingFieldException が出るかどうかの分かれ目です。

Json の設定項目の早見表(既定値はソースで確認)

既定値は v1.11.0 の JsonConfiguration のソースの値です。

設定 既定値 true(または値)にすると
ignoreUnknownKeys false クラスに無いキーを無視する
encodeDefaults false 既定値と同じ値も出力する
explicitNulls true false で、null を出力しない。読むとき無い nullable を null にする
prettyPrint false 改行・字下げして出力する
prettyPrintIndent " "(空白4つ) 字下げの文字を変える
coerceInputValues false null や知らない enum 値を、既定値に置き換える
isLenient false 引用符の無いキー・文字列を受け付ける
classDiscriminator "type" sealed・ポリモーフィズムの型名のキー
classDiscriminatorMode POLYMORPHIC 型名を出す範囲(実験的 API)
namingStrategy null SnakeCase・KebabCase でキー名を一括変換(実験的 API)
decodeEnumsCaseInsensitive false enum の名前を大文字小文字を区別せずに読む
useAlternativeNames true @JsonNames の別名を使う
allowTrailingComma false 末尾のカンマを受け付ける
allowComments false //・/* */ のコメントを受け付ける
allowSpecialFloatingPointValues false NaN・Infinity を受け付ける・出力する
allowStructuredMapKeys false Map のキーにオブジェクトを使える
useArrayPolymorphism false 型名を ["型名", {…}] の配列形式にする
exceptionsWithDebugInfo true false で、例外のメッセージに入力の JSON を含めない(実験的 API)
serializersModule 空 @Contextual や open なポリモーフィズム用の登録

設定ごとの実行結果

入力・操作 既定の設定 設定を変えたとき
{"id":1,"name":"A","age":30} を読む Encountered an unknown key 'age' ignoreUnknownKeys = true で User(id=1, name=A, …)
User(1, "Ito") を出力(encodeDefaults = true) {"id":1,"name":"Ito","email":null,"tags":[]} explicitNulls = false で {"id":1,"name":"Ito","tags":[]}
"status":null を既定値つき非 null に Expected string literal but 'null' literal was found coerceInputValues = true で既定値 DRAFT
"status":"archived"(知らない enum) Status does not contain element with name 'archived' coerceInputValues = true で既定値 DRAFT
"status":"PUBLISHED"(大文字) Status does not contain element with name 'PUBLISHED' decodeEnumsCaseInsensitive = true で PUBLISHED
{id:1,name:Ito} Expected quotation mark '"', but had 'i' instead isLenient = true で読めた
{"id":1,"name":"A",} Trailing comma before the end of JSON object allowTrailingComma = true で読めた
コメント入りの JSON — allowComments = true で読めた
Profile("ito", 1990) を出力 {"nickName":"ito","birthYear":1990} SnakeCase で {"nick_name":"ito","birth_year":1990}
Circle(Double.NaN) を出力 Unexpected special floating-point value NaN. allowSpecialFloatingPointValues = true で {"radius":NaN}

explicitNulls = false は、読むときにも効きます。 既定値の無い val note: String? が JSON に無いとき、既定の設定では MissingFieldException でしたが、explicitNulls = false では note=null で読めました。

coerceInputValues は、null と知らない enum 値のどちらも既定値に置き換えます。 既定値の無いプロパティでは置き換えられません。

prettyPrint = true の出力です。

{
    "id": 1,
    "name": "Ito"
}

REST API のクライアントでよく使う組み合わせ

val ApiJson = Json {
    ignoreUnknownKeys = true      // API 側が項目を足しても壊れない
    explicitNulls = false         // null を送らない・無い項目を null で読む
    coerceInputValues = true      // 想定外の enum 値を既定値で受ける
}

ignoreUnknownKeys は便利ですが、キー名の綴り違いにも気づかなくなります。自分たちで JSON を作る設定ファイルなどでは、既定の厳しい設定のほうが誤りを見つけやすくなります。

日付と時刻

java.time.LocalDate には、そのままでは対応していません。 @Serializable のクラスに LocalDate 型のプロパティを書くと、コンパイルの時点で止まりました。

error: serializer was not found for type 'LocalDate'. To use a context serializer as the fallback, explicitly annotate type or property with '@Contextual'.

方法は3つあります。

方法 使う型 向いている場面
kotlinx-datetime kotlinx.datetime.LocalDate など Kotlin だけで完結するコード・マルチプラットフォーム
kotlin.time.Instant 標準ライブラリの Instant 時点(UTC)だけを扱う
自作 KSerializer java.time.LocalDate など Spring など Java の型をそのまま使う

kotlinx-datetime を使う

kotlinx-datetime の型は、最初から @Serializable に対応しています。ISO 8601 の形式で出力されます。

// 依存:implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
import kotlinx.datetime.*
import kotlinx.datetime.format.*
import kotlinx.datetime.serializers.FormattedLocalDateSerializer
import kotlin.time.Instant

// 2026/10/12 の形式で読み書きする
object SlashDateSerializer : FormattedLocalDateSerializer(
    "com.example.SlashDate",
    LocalDate.Format { year(); char('/'); monthNumber(); char('/'); day() }
)

@Serializable
data class Reservation(
    val date: LocalDate,
    val start: LocalDateTime,
    val at: Instant,
    @Serializable(with = SlashDateSerializer::class) val shown: LocalDate,
)
{"date":"2026-10-12","start":"2026-10-12T09:30","at":"2026-10-12T00:30:00Z","shown":"2026/10/12"}
Reservation(date=2026-10-12, start=2026-10-12T09:30, at=2026-10-12T00:30:00Z, shown=2026-10-12)

存在しない日付("2026-13-01")を読むと、kotlinx.datetime.DateTimeFormatException(中身は Invalid value for MonthOfYear (valid values 1 - 12): 13)になりました。

kotlinx-datetime の README では、0.7.0 から Instant と Clock は標準ライブラリの kotlin.time のものを使う形に変わっています。kotlinx.serialization 1.11.0 には、kotlin.time.Instant 用のシリアライザが入っています。

java.time.LocalDate 用の KSerializer を書く

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.LocalDate

object LocalDateSerializer : KSerializer<LocalDate> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("java.time.LocalDate", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: LocalDate) =
        encoder.encodeString(value.toString())

    override fun deserialize(decoder: Decoder): LocalDate =
        LocalDate.parse(decoder.decodeString())
}

@Serializable
data class Event(
    val name: String,
    @Serializable(with = LocalDateSerializer::class) val date: LocalDate,
    val createdAt: kotlin.time.Instant,
)
{"name":"release","date":"2026-10-12","createdAt":"2026-10-12T01:02:03Z"}
Event(name=release, date=2026-10-12, createdAt=2026-10-12T01:02:03Z)
部品 書くこと
descriptor この型が JSON で何になるか。文字列なら PrimitiveKind.STRING。名前はアプリ内で重ならないようにする
serialize 値を encoder.encodeString(…) などで書く
deserialize decoder.decodeString() などで読んで値を作る

"2026/10/12" を読むと、java.time.format.DateTimeParseException: Text '2026/10/12' could not be parsed at index 4 がそのまま出ました。

@Contextual で一か所にまとめる

プロパティごとに with = を書かず、Json の設定で登録する方法です。

@Serializable
data class Holiday(val name: String, @Contextual val date: LocalDate)

val json = Json {
    serializersModule = SerializersModule {
        contextual(LocalDate::class, LocalDateSerializer)
    }
}
{"name":"sports-day","date":"2026-10-12"}

登録していない Json(素の Json)で同じクラスを出力すると、実行時に Serializer for class 'LocalDate' is not found. になりました。 @Contextual は「実行時に Json の設定から探す」という意味なので、使う Json すべてに登録が要ります。

Java の日付の書式は、関連記事「Kotlin 日付と時刻の扱い方 LocalDateのフォーマットと差分計算」で扱っています。

enum と sealed class

enum

enum は名前の文字列で出力されます。@SerialName で JSON 側の値を変えられます。知らない値が来たときは Status does not contain element with name 'archived' になり、coerceInputValues = true と既定値の組み合わせで既定値に置き換えられます(上の表)。enum の基本は、関連記事「Kotlin enum classの使い方 entries・valueOf一覧」で扱っています。

sealed class(ポリモーフィズム)

@Serializable
sealed interface Shape

@Serializable @SerialName("circle")
data class Circle(val radius: Double) : Shape

@Serializable @SerialName("rect")
data class Rect(val w: Double, val h: Double) : Shape

val shapes: List<Shape> = listOf(Circle(1.0), Rect(2.0, 3.0))
Json.encodeToString(shapes)
[{"type":"circle","radius":1.0},{"type":"rect","w":2.0,"h":3.0}]

sealed の親が @Serializable なら、子クラスは自動で登録されます。 型名は "type" というキーで入ります。値は @SerialName の値で、付けなければクラスの完全修飾名です。

書き方 出力
Json.encodeToString(Circle(1.0)) {"radius":1.0}(型名が付かない)
Json.encodeToString<Shape>(Circle(1.0)) {"type":"circle","radius":1.0}
Json { classDiscriminator = "@type" } {"@type":"circle","radius":1.0}
親に @JsonClassDiscriminator("kind") {"kind":"card","last4":"1234"}

変数の型が子クラスのままだと、型名が付きません。 読むときに親の型で受けるなら、書くときも encodeToString<Shape>(…) のように親の型を指定します。

読んだ JSON エラー
{"type":"triangle","a":1} Serializer for subclass 'triangle' is not found in the polymorphic scope of 'Shape'
{"radius":1.0}(型名なし) Class discriminator was missing and no default serializers were registered in the polymorphic scope of 'Shape'.

sealed class の基本は、関連記事「Kotlin sealed classの使い方 enumとの違いとwhen網羅」で扱っています。

value class・ジェネリクス・JsonElement

@Serializable @JvmInline
value class UserId(val value: Long)

@Serializable
data class Order(val id: Long, val userId: UserId)

@Serializable
data class Page<T>(val items: List<T>, val total: Int)
Json.encodeToString(Order(1, UserId(42)))
{"id":1,"userId":42}

Json.encodeToString(Page(listOf(User(1, "A")), 1))
{"items":[{"id":1,"name":"A"}],"total":1}

@Serializable の value class は、中身の値だけで出力されます({"value":42} にはならない)。value class の使い方は、関連記事「Kotlin value classの使い方|IDの取り違えを型で防ぐ」で扱っています。ジェネリクスのクラスも、decodeFromString<Page<User>>(…) のように型引数を書けば読めました。

クラスを作らずに JSON を扱うときは JsonElement を使います。

val el = Json.parseToJsonElement("""{"user":{"id":7,"name":"Ito"},"tags":["x","y"]}""")
el.jsonObject["user"]!!.jsonObject["name"]!!.jsonPrimitive.content   // Ito
el.jsonObject["user"]!!.jsonObject["id"]!!.jsonPrimitive.int         // 7
el.jsonObject["tags"]!!.jsonArray.size                               // 2

val built = buildJsonObject {
    put("id", 1)
    put("name", "Ito")
    putJsonArray("tags") { add("a"); add("b") }
}
// {"id":1,"name":"Ito","tags":["a","b"]}

Json.decodeFromJsonElement<User>(el.jsonObject["user"]!!)              // User(id=7, name=Ito, ...)

よくあるエラーと原因

エラー文は、v1.11.0 を実行して出たものです(JSON input: の行は省いたものもあります)。

エラー文(主な部分) 原因 直し方
Encountered an unknown key 'age' at path: $ クラスに無いキーが JSON にある ignoreUnknownKeys = true、クラスに @JsonIgnoreUnknownKeys、またはプロパティを足す
Field 'name' is required for type with serial name 'User', but it was missing at path: $(MissingFieldException) 既定値の無いプロパティが JSON に無い。@Required も同じ 既定値を付ける・nullable なら explicitNulls = false
Serializer for class 'X' is not found. @Serializable が無い・プラグインが無い・@Contextual の登録が無い 注釈・プラグイン・serializersModule を確かめる
serializer was not found for type 'LocalDate'(コンパイル時) プロパティの型が変換できない @Serializable(with = …) か @Contextual
Expected string literal but 'null' literal was found at path: $.name 非 null のプロパティに null が来た String? にする・既定値+coerceInputValues
Unexpected symbol 'a' in numeric literal at path: $.id 数値の項目に文字列が来た JSON かクラスの型を直す
Status does not contain element with name 'archived' 知らない enum 値 coerceInputValues+既定値、decodeEnumsCaseInsensitive
Expected start of the object '{', but had '[' instead 配列を1件のクラスで読んだ decodeFromString<List<User>>
Expected start of the object '{', but had 'EOF' instead 空文字を読んだ 読む前に空かを確かめる
Expected end of the object '}', but had 'EOF' instead JSON が途中で切れている 入力を確かめる
Serializer for subclass 'triangle' is not found in the polymorphic scope of 'Shape' sealed に無い型名 子クラスを足す・@SerialName を合わせる
Class discriminator was missing … sealed の JSON に型名のキーが無い "type" を入れる・classDiscriminator を合わせる

エラー文の at path: $.status は、JSON の中のどこで止まったかを示します。 $ が一番外のオブジェクトで、$.items[0].name のように深くなります。

例外の種類

例外 いつ出るか
SerializationException すべての親。シリアライザが無い、enum の値が無い など
MissingFieldException 必須の項目が無い(SerializationException の子)
JsonDecodingException JSON の読み込みでの誤り(1.11.0 から公開。実験的 API)
JsonEncodingException JSON の書き出しでの誤り(NaN など)

1.11.0 の CHANGELOG では、JsonDecodingException などが公開され、path・offset などのプロパティを持つようになったとあります。REST API でエラーの場所を返すときに使えます。

エラー文に入力の JSON を出したくないとき

既定では、エラー文の最後に JSON input: {…} として入力が入ります。パスワードなどがログに残るのを避けたいときは、1.11.0 で入った exceptionsWithDebugInfo = false(実験的 API)を使います。実行すると、JSON input: の行が消えました。CHANGELOG では、この動きは安定版になったときに既定になる予定とされています。

よくある質問

Q. Jackson と比べて何が違いますか。 A. kotlinx.serialization はコンパイル時に変換コードを作るので、リフレクションを使いません。Kotlin の既定値・null 許容をそのまま扱え、マルチプラットフォーム(JS・Native)でも動きます。Jackson は Java の型や注釈の資産が多く、Spring の既定です。Jackson の使い方は、関連記事「Jackson ObjectMapperの使い方|JSON変換・日付・record」で扱っています。

Q. Ktor で使うには? A. Ktor の ContentNegotiation に json() を登録すると、kotlinx.serialization で JSON を変換します。関連記事「Ktor 入門|REST APIをJSON・例外処理・テストまで作る」で扱っています。

Q. data class でなくても使えますか。 A. 使えます。kotlinx.serialization のガイドでは、バッキングフィールド(値を入れておく場所)を持つプロパティが対象とされています。計算するだけの get() のプロパティは出力されません。data class の基本は、関連記事「Kotlin data classの使い方|copy・equalsとclass差」で扱っています。

まとめ

  • プラグイン(kotlin("plugin.serialization"))とライブラリの両方を入れる。プラグインが無いと実行時に Serializer for class … is not found
  • 既定値と同じ値は出力されない(encodeDefaults = false)。既定値の無いプロパティは JSON に必須
  • API のクライアントには ignoreUnknownKeys・explicitNulls = false・coerceInputValues の組み合わせ
  • Json は使い回す。毎回作るとプラグインが警告を出した
  • 日付は kotlinx-datetime か 自作 KSerializer。java.time.LocalDate はそのままではコンパイルエラー
  • sealed は親の型で encodeToString<Shape> すると "type" の型名が付く

参考・出典

確認日はいずれも 2026年10月12日です。

  • Kotlin ドキュメント「Serialization」(Get started):https://kotlinlang.org/docs/serialization-get-started.html
  • kotlinx.serialization(GitHub、ソース・ガイド・タグ v1.11.0):https://github.com/Kotlin/kotlinx.serialization
  • kotlinx.serialization CHANGELOG:https://github.com/Kotlin/kotlinx.serialization/blob/master/CHANGELOG.md
  • kotlinx.serialization ガイド「JSON features」:https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md
  • kotlinx-datetime(GitHub、README・CHANGELOG・タグ v0.8.0):https://github.com/Kotlin/kotlinx-datetime

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「kotlinx.serialization使い方|JSON変換・設定一覧・エラー」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?