第637回 SORACOM公式ブログ

ソラコム公式ブログ

Connectivity Hypervisor 向け検索機能の舞台裏 ― サマーインターンで経験した設計と実装

  • この記事をはてなブックマークに追加
  • 本文印刷

 本記事はソラコムが提供する「SORACOM公式ブログ」に掲載された「Connectivity Hypervisor 向け検索機能の舞台裏 ― サマーインターンで経験した設計と実装」を再編集したものです。

こんにちは。ソラコムでインターンをしている Soma です。

インターン参加の背景と目的

7月から Automotive/MVNE チームにジョインし、SORACOM Connectivity Hypervisor まわりを担当しています。渡されたお題は「Connectivity Hypervisor の SIM を検索できるようにする」という、たった一行でした。

商用提供が始まったばかりのグローバル向けサービスに、実際にお客様が使う機能をゼロから通しで組み込む。しかも、お題が一行ということは、どう作るかは自分で決めていいということです。API をどう定義するかから任せてもらえるのか、というのが最初の驚きでした。

着手した時点では、正直「既存の SIM 検索と同じものをもう一つ作るだけかな?」と思っていました。しかし蓋を開けてみると、データモデルが根本から違い、5つのリポジトリ・4種類のプログラミング言語にまたがる設計が必要で、API の仕様も自分で決める。想像していたより、何段も奥行きのあるミッションでした。

その入り口にあるのが、1枚の SIM が複数の通信プロファイルを持つという構造です。データの入れ子がもう一段深くなる。それだけの違いが、検索という機能の設計を根本から変えてしまいました。

この記事では、Connectivity Hypervisor とは何かから始めて、既存の SIM 検索と何が違うのか、そして「検索機能」と一言で呼ばれるものの実体が何だったのかを書きます。

SORACOM Connectivity Hypervisor とは

これまで IoT デバイスの通信は、製造時の決め打ちでした。出荷先を決め、キャリアを選び、SIM を基板に載せる。出荷した瞬間に構成が確定し、あとから変えるにはデバイスを回収するしかありません。製品寿命が10年を超える車載機器やスマートメーターでは、旧世代ネットワークの終了や法規制の変更に対応しきれません。

これを解決するのが、GSMA が策定した SGP.32 です。IoT 機器向けの eUICC リモートプロビジョニング規格で、画面も操作する人もいないデバイスを前提に、通信事業者のプロファイルを OTA(無線経由)で配信・切り替え・管理できます。

用語を先に整理しておきます。以降はこの意味で使います。

意味 出典
eUICC リモートからプロファイルを書き換えられる SIM チップ GSMA の標準規格
プロファイル 1回線分の設定一式。どの通信事業者のどの契約で通信するかが入っている GSMA の標準規格
ICCID プロファイルを識別する番号 国際標準
IMSI 回線(加入者)を識別する番号 国際標準
SIM ID SORACOM が独自に SIM へ割り当てる識別子 SORACOM 独自
サブスクリプション SORACOM の回線契約の種類(planX1 など) SORACOM 独自

SORACOM Connectivity Hypervisor は、SGP.32 に準拠したオーケストレーション層(プロファイルの管理をまとめて引き受ける層)です。ユーザーコンソールや API から、プロファイルの追加、有効プロファイルの切り替えと削除、主プロファイルが使えないときのフォールバック先(退避先)の指定ができます。2025年7月に発表し、2026年7月7日に SGP.32 対応 IoT SIM の提供を開始しました。

1万枚の進捗を、1枚ずつは追えない

まず、扱う数が違います。Connectivity Hypervisor が想定しているのは、自動車メーカーのようにグローバルへ大量出荷するお客様です。1社が抱える SIM は、数枚ではなく数万枚の単位になります。

次に、操作がすぐには終わりません。プロファイルの操作は、SIM 上のエージェントと SORACOM のあいだのポーリングで反映されます。その間隔はデフォルトで24時間に1回。デバイスの電源が入っていなければ、そのぶん先に延びます。プロファイルがダウンロードされるまでに「数分から数日程度かかる場合があります」と案内されているのは、そのためです。

つまり、指示を出してから完了するまで日をまたぐのが正常系です。異常ではありません。数万枚に一括で指示を出せば、しばらくのあいだ「終わったもの」と「まだのもの」が混在し続けます。

だから、進捗を把握する手段が要ります。1枚だけなら追えます。SIM ハイパーバイザー画面の [イベント履歴] タブに、その SIM の操作が並ぶからです。問題は、1万枚を1枚ずつ開くわけにはいかないことでした。

「先週指示した1万枚のうち、まだ切り替わっていないのはどれか」。SIM の一覧はタグやグループでの絞り込みには対応していましたが、この問いに答えるには、従来の SIM にない軸が要ります。

既存の SIM 検索とは、ここが決定的に違う

先に誤解を潰しておきます。「1枚の SIM が複数の回線を持つ」こと自体は、Connectivity Hypervisor で初めて登場したわけではありません。

SORACOM にはサブスクリプションコンテナ機能という「1 つの IoT SIM に複数のサブスクリプション(回線=IMSI)を保存する」機能を2020年から提供しており、その頃から1つの IoT SIM に複数の IMSI がぶら下がるようになりました(セカンダリサブスクリプション)。

この時生まれたのが、複数の IMSI を束ねて管理する SORACOM 独自の識別子「SIM ID」です。実際、既存の SIM 検索のインデックスも IMSI を配列で保持しています。SIM ID : IMSI = 1:N は、この頃からある構造です。

Connectivity Hypervisor で変わったのは、あいだに「プロファイル」という層が1段挟まったことでした。

プロファイルは ICCID で識別され、種別(planX1 など)を持ちます。そして複数持てますが、有効になれるのは同時に1つだけです。

サブスクリプションコンテナとの違いは、コンテナがデバイスのいる国や地域に応じて自動で選ばれるのに対し、Connectivity Hypervisor はユーザーが任意のタイミングで有効化することです。加えて、他の通信事業者のプロファイルも載せられます。

選択がユーザーの手に移った。だから「いまどれを選んでいるか」を知る必要が生まれました。

ここから、検索条件が2つ増えます。増えた中間層そのものを指す軸と、その層の状態を指す軸です。

  • profile_type:その種別のプロファイルを持っているか(有効・無効を問わない)
  • active_profile_typeいま、その種別で動いているか

長い時間をかけて進む操作を追う文脈では、この2つの差分こそが進捗です。たとえば「planX1 を持っている SIM」が1万件、「planX1 で動いている SIM」が7千件なら、差の3千件がまだ切り替わっていない SIM です。中間層が無ければ成り立たない引き算で、既存の SIM 検索に対応する条件はありません。

条件を足すだけでなく、あえて入れなかったものもあります。既存の SIM 検索にある search_type、AND / OR の切り替えです。

既存の SIM 検索では、複数の条件をすべて満たすもの(AND)か、いずれかを満たすもの(OR)かを、呼び出し側が選べます。eUICC の検索では、これを「同じパラメータ内の値は OR、パラメータどうしは AND」に固定しました。たとえば module_type=mini,micro&active_profile_type=SGEPR31 は、モジュールタイプ(SIM の形状)が mini または micro で、かつアクティブなプロファイルが SGEPR31 の eUICC に一致します。

固定にしたのは、プロファイル軸の絞り込みでは「A か B を持ち、かつモジュールタイプが nano」という形が自然で、パラメータどうしを OR で結ぶ使いどころを説明できなかったからです。パラメータは後から足せますが、一度公開したものを消すのは困難です。この非対称性から、必要性を説明できないものは入れないという判断をしました。

UI は「既存の踏襲」で終わらせない

打てる条件が決まったら、次はそれをどう打たせるかです。ユーザーが最初に触るのは API でもインデックスでもなく検索ボックスなので、そこから作りました

API に繋ぐ前に、モックアップだけを先に作っています。検索体験は「どんな条件が打てるか」より「打ちやすいか」で決まるので、API を作り込んでから UX を直すのは高くつくと思ったからです。フロントエンドのチームに動画で共有して、方向性のレビューをもらいました。

ベースは既存の SIM 検索です。ただ、並べて操作すると、踏襲しないほうがよい点が3つ見つかりました。

1. フィルタの有効化チェックボックスをなくす

既存の SIM 検索では、絞り込み項目ごとに左端のチェックボックスをオンにしないと、選択肢を押せません。「使う項目を選ぶ → 値を選ぶ」の2ステップです。

この1段目は、実装から見れば「この項目を条件に含めるか」というフラグです。しかしユーザーから見ると、値を選ぶ前の空回りでしかありません。値を選んだのにチェックを入れ忘れて絞り込まれない、という取り違えも起こります。

新しい検索ボックスでは、この段を外しました。値を選べば条件になり、外せば条件から消えます。UI に出ていたのは実装の内部状態だったので、外に出す必要がありませんでした。search_type を入れなかったのも、根は同じです。

2. 条件は1つずつ外せるようにする

検索を実行すると、いま何で絞り込まれているかが検索バーに表示されます。

既存では、選んだ値がひとまとまりのテキストになります。ここから「ナノだけ外したい」と思うと、フォームを開き直して選び直すことになります。1つ変えるために、条件全体を組み直す必要がある。

新しい検索ボックスでは、値ごとに独立したチップにしました。× を押すとその値だけが条件から外れ、残りはそのまま検索し直されます。

検索は一発で決まることが少なく、条件を足したり引いたりしながら目的の集合に寄せていく作業です。試行錯誤1回あたりの手数を減らすことが、体感の速さにいちばん効きます。

3. 直前の検索に戻れるようにする

3つ目は、既存にはない検索履歴です。検索ボックスを開くと直近の条件が並び、クリックすればそのまま再適用されます。

これも 2 と同じ理由です。絞り込みの途中では「さっきの条件に戻したい」が頻繁に起きます。手で組み直すのは、結果が同じでもやり直しの体感になります。

おまけ — ここにも 1:N がいた

UI で選ぶのはプラン名planX1 など)ですが、API が受け取るのはプロダクトコードSGEPR21SGEPR31 など)です。しかも対応は 1:1 ではありません。1つのプラン名が複数のプロダクトコードに対応します。

planX1  → SGEPR21, SGEPR31 plan01s → SGEPR23, SGEPR33 

つまりプラン名をそのまま API に投げると、エラーにならず、静かに0件が返ります。検索は、バグと「該当なし」がユーザーから区別できない機能です。どちらも同じ空のテーブルに見える。

そこで、検索条件の型はプラン名のまま保持し(フォーム・チップ・検索履歴が、ユーザーの選んだ値をそのまま往復できるように)、API へ渡す直前の1箇所だけでプロダクトコードに展開するようにしました。気をつけて防ぐのではなく、忘れる余地を構造的になくす方針です。


ここまでが、お客様の目に触れる部分です。

着手する前は、この検索ボックスと、その裏に API がひとつあれば済むと思っていました。UI とバックエンド、それだけだと。実際には、そう単純ではありませんでした。

「検索機能」の実体は、5つの層だった

実際に触ったのは、次の5つの層でした。

1. API 定義 — 自分が書いた行が、お客様の触る API になる

SORACOM の API は定義ファイル(OpenAPI)が単一の情報源になっていて、ここに書いたものがそのまま公開され、API リファレンスと SORACOM CLI が生成されます。今回追加したのは GET /v1/query/euiccs です。

つまり、自分が書いた行が、そのままお客様の触る API になる。インターンで最初に任されたのがここだと知ったときは、正直ひるみました。

そのぶん、決めたことは全部説明できるようにしました。前章の「search_type を入れない」も、実装ではなくこの時点の決定です。そして結果的に、これが一番効きました。API 定義が3つの層の契約になったので、インデックス側(何をインデックスすべきか)、検索 API 側(何を受け取るべきか)、UI 側(何を打たせるか)を並行して進められたからです。

2. インデックス構築 — テーブルに無いものを、どう検索させるか

まず前提から。SIM の情報は Amazon DynamoDB(以下、DynamoDB) に保存されています。DynamoDB は主キー中心の読み取りには強い一方、「タグに X を含み、かつプロファイル種別が Y で、かつオフライン」のような多軸の絞り込みには向きません

そこで SORACOM では、検索を Amazon OpenSearch Service(Elasticsearch 7 互換の API を持つ AWS のマネージドサービス)が担っています。書き込み先と検索先が別なので、両者を繋ぐ必要がある。その役目が DynamoDB Streams です。テーブルの変更がイベントとして流れてきて、それを購読した AWS Lambda(以下、Lambda)がインデックスを更新します。今回はこの Lambda を新設しました(Go)。

ストリームだけで済む部分

ストリームのイベントは SIM の全状態を含むので、大半のフィールドは外部参照なしで変換できます。

ここで詰まったのが、「今このプロファイルで動いている SIM」がインデックス上で表現できないことでした。

プロファイルの配列そのものは、完全なスナップショットを _source に持たせたいだけなので、マッピングでは検索対象外のオブジェクトにしています。つまりクエリから中を覗けない。そこで、検索したい値はトップレベルへ平坦化しました。「どの ICCID を持つか」「どの種別を持つか」は、profileIccidsprofileTypes という配列にすれば済みます。

ところが、「今どれが有効か」だけは配列にできません。配列は「持っている」ことしか表せず、そのうちどれが動いているかを指せないからです。ここだけは、有効なプロファイルの種別を activeProfileType という単独のフィールドとして別に持たせる必要がありました。

profile_type は配列に、active_profile_type はスカラーに。前章で分けた2つの条件が、インデックスの型の違いとしてそのまま現れています。

モデルの違いによる、合成の問題

ここからが本題です。検索したい IMSI とセッション状態(デバイスがいま通信できているか)は、eUICC のテーブルに存在しません。契約側にあります。しかも前章で見たとおり、1つの SIM ID に対して複数

つまり、別テーブルにある 1:N のデータを引いてきて、インデックス上の1件(ドキュメント)に畳み込む必要があります。これがモデルの違いから来る、いちばん面倒な部分でした。

そして、ここに落とし穴がありました。これらは eUICC のテーブルが1バイトも書き換わらないまま変化します。デバイスがオンラインになるのは契約側の出来事だからです。Amazon DynamoDB Streams(以下、Streams)は「そのテーブルの変更」しか流さないので、eUICC 側のストリームだけを見ていても永遠に気づけません。契約側のストリームを購読する専用のインデクサをもうひとつ追加して、影響を受けるドキュメントを丸ごと再構築するようにしました。図のインデクサが2つあるのは、このためです。

外部サービスへの問い合わせが失敗したときは、バッチ全体を失敗させて Streams のリトライに委ねます。ストリーム由来の情報だけで「一見妥当に見えるドキュメント」を書いてしまうと、IMSI とセッション情報が欠けたまま、次に同じ SIM が書き換わるまで誰も気づきません。サイレントに壊れたインデックスより、リトライされる失敗のほうがずっとマシです。

そして、性能の問題

合成が正しくできるようになると、次は回数が問題になります。

ストリームは一度に複数件のイベントを運んできます。1件ずつ問い合わせれば、イベント数と同じ回数の外部呼び出しが発生する。アカウント単位でまとめて100件ずつのバッチにすることで、1バッチあたり数回の呼び出しで済むようにしました。このバッチ取得そのものは自分で作る必要があったのですが、詳しくはこの章の 4 で書きます。

なお、インデクサはデプロイ後に発生した変更しか見ません。それ以前から存在する SIM を埋めるための初期投入バッチも別に用意しました。

3. 検索 API — 検索はインデックス、返す中身は権威ソース

GET /v1/query/euiccs の実装です(Java と Groovy)。インデックスを検索して SIM ID を得て、その ID で本体を再取得する2段構成にしました。

インデックスは非同期に更新されるので、常に少し古い可能性があります。そこで「検索はインデックス、返す中身は権威ソース」——正となるデータを持っている側から改めて取り直す——と役割を分けました。次ページのカーソルも、再取得の結果ではなくインデックスのヒットから導出しています。

セマンティクスでいちばん悩んだのが、session_status=OFFLINE の意味でした。インデックスは三状態を持ちます。オンライン、オフライン、そしてセッション状態のフィールド自体が存在しない(一度も接続していない、または取得できなかった)状態です。素直に「オンライン = false」で判定すると、三番目が黙って結果から消えます。一度も繋がっていない SIM が「オフライン検索」に出てこないのは、明らかに意図と違う。なので「オンラインではない」として実装しました。

どの属性の値か分からないまま検索するための any は、展開先を sim_id / name / imsi / iccid / tag の識別子系だけに絞りました。module_typeprofile_type は含めていません。これらは呼び出し側が明示的に選ぶフィルタであって、ユーザーがどこかからコピーして貼り付ける識別子ではないからです。広げれば広げるほど親切に見えて、実際はノイズが増えます。

細かいところでは、検索語の長さに下限と上限を設けています。下限は2文字。上限のほうは、長すぎる値を渡すと Lucene 側の処理限界に当たって検索エンジンがエラーを返すため、API の手前で弾いて、意味のあるエラーとして返すようにしました。下位ミドルウェアのエラーをそのまま漏らさないのも API の仕事だと思っています。

4. eUICC 管理サービス — 検索 API 側だけでは直せなかった

検索は1ページ最大100件を返します。ここで SIM ID ごとに個別の取得 API を呼ぶと、1ページあたり100回の HTTP 呼び出しです。レイテンシもエラー発生率も、呼び出し回数に比例して上がります。100回のうち1回失敗すればページ全体が壊れる。

問題は、検索 API 側だけでは対処しようがないことでした。呼ぶ先にバッチ取得が存在しない以上、呼び出し方をどう工夫しても N 回は N 回のままです。そこで、eUICC 管理サービス側にバッチ取得エンドポイントを実装しました(TypeScript)。検索機能をつくるつもりで、隣のサービスの API を設計していたわけです。

契約は、すでに SIM 側にある同じ形のバッチ取得に揃えました。

挙動
リクエスト アカウント(オペレーター)ID + SIM ID の配列
レスポンス リクエストと同じ順序の配列、ページングなし
上限 100件。超えたらエラー
存在しない ID 黙って省く(エラーにしない)
重複 まとめる

「存在しない ID をエラーにしない」は、この用途では重要でした。検索インデックスは非同期更新なので、インデックスには載っているが既に削除されている SIM が混ざりえます。そこでエラーを返すと、1件の古い ID がページ全体を巻き添えにする。その代わりレスポンスがリクエストより短くなり得るので、呼び出し側は位置で突合してはいけません

上限を100にしたのは、3つが同時に効くからです。既存のバッチ取得と同じ上限であること、DynamoDB の BatchGetItem が1リクエストで扱えるキー数の上限と同じであること、そしてプロファイル取得の並列数を考えるとこれ以上増やしても待ち時間が伸びるだけであること。

正直に書いておくと、HTTP の N+1 を消しても、プロファイル取得側の N+1 は残っています。やったのは100回の HTTP 往復と99回の本体読み取りを消したことであって、もともとあった N+1 は引き継いでいる。ここを「N+1 を解消した」と書くと、次に触る人が「もう速いはずだ」と誤解します。PR には消えた分と残った分の内訳を分けて書き、別の課題として切り出しました。

このとき、既存コードのバグをひとつ掘り当てました。バッチ読み取りを既存の一覧取得と共通化したところ、既存側が BatchGetItemUnprocessedKeys を見ていないことに気づいたのです。DynamoDB はスロットリング時、エラーではなく成功レスポンスの中で「これは読めませんでした」と返します。それを無視していたので、負荷が高いときに一部の SIM が黙って一覧から消えていた。共通化のついでに直りました。

このバッチ取得は、結局3箇所で使われることになりました。検索 API の再取得、そして2つのインデクサの合成処理です。どれも「複数の SIM ID を持っていて、その中身が要る」という同じ形をしていました。

そして、使われ方とは別の効き方もしました。当初、セッション状態だけでの検索は禁止していたのです。「オフライン」は未接続の SIM も含むので全走査に近く、しかもヒット1件ごとに外部呼び出しが発生していたからです。バッチ取得によってその費用が件数に比例しなくなったので、セッション状態も他の条件と同じように単独で使えるようになりました

隣のサービスに足した API が、検索 API の仕様上の制約まで解いた。層をまたいで作ると、こういうことが起きるのだと知りました。

5. UI — 4層あって、ようやく動く画面

前章で見た検索ボックスです。条件を組み立てて GET /v1/query/euiccs を呼び、返ってきた eUICC を表に並べます。ここまでの4層があって、ようやくあの画面が動きます。

インターンを通して学んだこと

設計について

データモデルが変われば、機能の全部が変わる。振り返ると、この機能の設計判断はほとんどが「あいだにプロファイルの層が1段増えた」という一点から導かれていました。API の検索条件も、インデックスの持ち方も、UI の見せ方もです。既存実装をコピーせず、モデルの違いから考え直したことが、結果的に近道でした。

面白かったのは、増えた中間層をどう表現するかが、層ごとに違う形を取ったことです。API 仕様では profile_typeactive_profile_type という2つのパラメータとして。インデックスでは配列とスカラーの使い分けとして。UI ではプラン名とプロダクトコードの展開として。同じ一点から出ているのに、扱う場所ごとに違う対処を要求してきました。

参照と更新では、データの形が違う。更新に都合のよい形と、検索に都合のよい形は同じではありません。DynamoDB には SIM の状態がそのままの構造で入っていますが、検索するには「どの種別を持つか」を配列に平坦化し、「今どれが有効か」をスカラーに引き出す必要がありました。これが CQRS と呼ばれる考え方だと知ったのは、レビューで指摘されてからです。自分が手で作っていたものに、ちゃんと名前が付いていたというのは、なかなか面白い体験でした。

1つの機能が、1つのリポジトリに収まるとは限らない。個人開発では、機能を1つ作ることとリポジトリを1つ触ることは、だいたい同じでした。ここでは違います。「検索を作る」という1つの機能のために5つのリポジトリを触り、最後には担当ですらない隣のサービスに API を足しています。どこまでが自分の仕事かは、コードの区切りでは決まらないのだと思いました。

一度公開したものは戻せない。search_type を入れなかったのは、「後から足せるが、消すのは難しい」という非対称性に気づいたからです。自分だけが使うコードなら、この判断は要りませんでした。

技術について

Amazon OpenSearch Service も Amazon DynamoDB も、触るのは今回が初めてでした。資料で読んで知っているのと、ストリームを流して実際にインデックスが更新されるのを見るのとでは、理解の質がまるで違いました。「たぶんこう動く」が「こう動く」に変わったのが、この夏いちばん大きかったと思います。

プログラミング言語も、Go・Java・Groovy・TypeScript を行き来しました。最初は切り替えのたびに手が止まりましたが、層ごとに向いている道具が違うだけだと分かってからは、それほど苦になりませんでした。

開発環境について

Claude Code が、会社から用意されていました。インターンにも初日から配られます。

驚いたのは、それが「使ってもいいツール」ではなく、リポジトリ側が使われる前提で整備されていたことです。担当したユーザーコンソールのリポジトリには .claude/skills というディレクトリがあり、この会社のやり方が知識として置いてありました。

  • コーディングガイドラインに沿っているかを PR 単位でチェックするもの
  • デザインシステム(SDS)に沿った HTML / CSS を書くためのもの
  • Angular の書き方をガイドするもの
  • E2E テストの書き方をガイドするもの

効いたのは、レビューに出す前に自分でガイドライン準拠を確認できることでした。命名や構成の指摘を先に潰しておけるので、人のレビューでは設計そのものの議論に時間を使えます。UI の章で触れた検索ボックスも、デザインシステムの skill を見ながら組んでいます。

社内 bot も、あちこちで実際に動いていました。これまで参加した他社のインターンでも社内ツールはありましたが、ここまで日常的に使い倒されている環境は初めてで、素直に感動しました。ツールがあることと、ツールが使われていることは、別のことなのだと思います。

もうひとつ、習慣が変わりました。「なぜ他の選択肢を採らなかったか」を書き残すことです。差分を読めば何をしたかは分かりますが、採らなかった道はコードのどこにも残りません。PR に「レビューしてほしい設計判断」という節を設けて書くようにしたら、議論がその場で噛み合うようになりました。3日後の自分は、理由を思い出せませんから。

チームについて

配属された Automotive/MVNE チームは、自動車メーカーのお客様と、自社で通信事業を手がけるお客様(MVNE = Mobile Virtual Network Enabler)を担当しています。2025年に立ち上がったばかりの新しいチームで、Connectivity Hypervisor もその領域のひとつです。

インターンはリモート中心で進めました。チームマネージャーの factory、メンターの hiroki に相談しながら、5つのリポジトリを行き来する日々です。

——と、ここまで「さん」を付けずに書いてきました。SORACOM にはニックネームで呼び合う文化があり、社員どうしも呼び捨てです(公式ブログのインタビュー記事でも、ニックネームで紹介されています)。最初はかなり戸惑いました。相手は自分よりずっと経験のある方たちなので、呼び捨てにする違和感がなかなか抜けません。

ただ慣れてくると、これが効いてきます。呼び方に上下がないと、質問するときの心理的な段差もなくなるのです。「こんなことを聞いていいのだろうか」と考える時間が、目に見えて減りました。分からないことを分からないと言える速さは、インターンの成果に直結したと思います。

印象に残っているのは、UI のモックアップをフロントエンドチームに共有したときです。このチームとは英語でやりとりするので、画面を操作しながら英語で説明した動画を撮って送りました。SORACOM の開発チームが世界に分散していることを、そこで初めて肌で感じました。

課題と、これから

数万枚規模での実測はできていません。「設計上こうなるはず」と「実際にこうなった」のあいだには距離があると思っています。バッチ取得のところで書いた、プロファイル取得側に残った N+1 も、実際どこで問題になるかはまだ推定の域を出ません。

また、配属直後は eUICC や SGP.32 といった用語を追うだけで精一杯でした。この記事の前半は、そのとき自分が知りたかった順番で書いています。

検索は入口でしかありません。絞り込んだ結果への一括操作や、進捗を継続して観測する手段が、この先に必要になるはずです。「1枚の SIM に複数のプロファイルが載る」という新しい世界を運用するためのツールは、これから順に増えていくのだと思います。

― ソラコム インターン soma

参考リンク

投稿 Connectivity Hypervisor 向け検索機能の舞台裏 ― サマーインターンで経験した設計と実装SORACOM公式ブログ に最初に表示されました。

本記事はアフィリエイトプログラムによる収益を得ている場合があります

この連載の記事

過去記事アーカイブ

2026年
01月
02月
03月
04月
05月
06月
07月
08月
2025年
01月
02月
03月
04月
05月
06月
07月
08月
09月
10月
11月
12月
2024年
01月
02月
03月
04月
05月
06月
07月
08月
09月
10月
11月
12月
2023年
01月
02月
03月
04月
05月
06月
07月
08月
09月
10月
11月
12月
2022年
01月
02月
03月
04月
05月
06月
07月
08月
09月
10月
11月
12月
2021年
01月
02月
03月
04月
05月
06月
07月
08月
09月
10月
11月
12月