Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

Developers Summit 2019 Summerで弊社田中がエンジニアのキャリアについてお話させていただきました

みなさん、こんにちは。開発部エンジニア平木です。

少しレポートまで間が空いてしまいましたが、去る7/2(月)にソラシティカンファレンスセンターで開催されたDevelopers Summit 2019 Summerにメドレーが協賛させていただきました。

また、弊社の開発部長である田中がSI × Webの総合力で切り拓く新しいエンジニアのキャリアパスというタイトルのセッションでお話をさせていただきましたので、レポートを書きたいと思います。

会場の雰囲気

f:id:medley_inc:20190719173752j:plain
会場入口の立て看板がステキでした

会場ですがやはり今回も来場者が多く、セッション前には列が出来ていました。休憩時間中のブースにも人だかりといった感じで熱気を感じました。

f:id:medley_inc:20190719172816j:plain
次のセッション待ちで長蛇の列が
f:id:medley_inc:20190719172807j:plain
ブースも人が切れませんでした
しかしながら、運営が大変にスムーズだったので大きな混乱もなく次々と快適にセッションが見られるのは、やはり今までの経験によるものだろうなーと感じました。

印象に残ったセッション

f:id:medley_inc:20190719174247j:plain

色々とセッションを見ましたが、個人的にはやはり、@t-wadaさんのセッションは何度見ても惹き込まれるなと今回も拝見して感じました。

f:id:medley_inc:20190719173721j:plain

今回の内容を聞くと例え、全くテストを導入していないようなプロジェクトだったとしても「明日からちょっとずつやっていこう」と勇気をもらえるような内容でした。

f:id:medley_inc:20190719173729j:plain

エンジニアのキャリアパス

f:id:medley_inc:20190719173659j:plain

いよいよ、弊社田中のセッションです。残念ながら、資料は非公開とさせていただいています…。申し訳ありません。

f:id:medley_inc:20190719174601j:plain

内容としては、少し前まではいわゆるSIerとWeb系という2つの領域で結構明確に壁を感じることもあったと思います。しかし、近年X-Techなどの文脈では、関連省庁の法令やガイドラインなどを遵守しつつ、使いやすいUIへの落とし込みやマネージドサービスを使用したインフラの構築などを設計する必要があります。これらの設計の上で、Webサービスとして高速にPDCAを回しサービスを改善していくという能力も他方で必要になります。

f:id:medley_inc:20190719174328j:plain

こういった背景により、きっちりとした要件定義や設計する能力を求められるSIer的な要素と手を動かして早くサービスを改善するサイクルを回す能力が必要なWeb的な要素という、それぞれの得意領域をミックスしたエンジニアが求められているのではないかというお話をさせていただきました。

f:id:medley_inc:20190719173302j:plain

途中田中のキャリア変遷や、弊社のCLINICSを例に取り具体的にどのような能力を求められるのか?ということをお話させていただきました。

終了後のアンケートなど拝見する限り、やはり業界の括りに囚われがちなところも多いなか、キャリアパスの一つの実例として、ご好評をいただいたのは嬉しい限りでした。

まとめ

メドレーのエンジニアやデザイナーは、きっちりと法令やガイドラインを守りつつ、その概念をプロダクトの設計に落しこみ、出来るだけ早くPDCAを回し、早く確実に実装することを目指しています。Developers Summit 2019 Summerのような多種多様なキャリアの方々が来場するイベントで、このようなお話をさせていただいたのはとても有意義だったと感じています。

f:id:medley_inc:20190719173131j:plain
セッションが無事終了し、ほっと一息付きながらメドレーロゴと一緒に

▼メドレーってどんな会社?気になった方はこちら www.medley.jp

データウェアハウスとして使うAmazon Redshiftについて

はじめに

こんにちは。開発本部の阪本です。

今回は私が社内勉強会(TechLunch)にてAmazon Redshift(以下Redshift)についてお話した内容を紹介させていただきます。

Redshiftとは

概要

f:id:medley_inc:20190701165024p:plain RedshiftとはAWSサービスが提供しているデータウェアハウスで、高可用/高パフォーマンス/柔軟なスケーラビリティを実現しているのが特徴です。

競合としてはBigQueryHadoop、また同じAWSサービスではAmazon Athenaも同様の位置付けになると思います。

データベースとしての特徴

Redshiftの特徴として、列志向型データベースという点があります。

MySQLのようなリレーショナルデータベースはデータを行(レコード)単位で保持している事に対し、Redshiftは列単位で保持しています。

f:id:medley_inc:20190701165052p:plainf:id:medley_inc:20190701165052p:plain 列単位でデータを持っているため集計クエリのような特定の列に対して大量の行を精査するのが高速である反面、行を特定してのアクセスはMySQLPostgreSQLのような行志向のデータベースに比べてのクエリに比べて遅い傾向にあります。

またデータにはSQLでアクセスすることができ、構文もPostgreSQLと互換性があります。 最近スキーマレスなデータベースなどが多く出てきていますが、Redshiftは事前にテーブルを作成する必要のある従来型のRDBMSの形となっており、テーブル作成時はCREATE TABLEといったデータ定義言語(DDL)を使うことになります。

機能面の特徴

f:id:medley_inc:20190701165113p:plain:w350 先にも書きましたが、データアクセス時に使うSQLPostgreSQLの構文と互換性があります。

よってPostgreSQL用ドライバ(JDBC含む)さえ使えれば、後は特別に意識することなくRedshiftに対して接続やクエリ発行が行えるということになります。

この恩恵はプログラムだけではなく他社が展開しているサービスにも受けることができ、BIツールのTableauRedashなどもそのままデータソースとして利用することが出来ます。

次に、一般的なRDBMSとの差についてです。 RDBMSにはありRedshiftには無いものとしては - UNIQUE制約 - 外部キー制約 - インデックスが無い

などがあります。

インデックスに関しては遠い意味での代用品(Sort Key)があるものの、基本的には使うことが出来ません。 注意点としてクエリ自体はPostgreSQL互換なのでこれらを作るDDL構文を受け入れてくれるますが、Redshiftでは無視されますのでご注意ください。

逆に、Redshift固有のものとしては - Sort Key - 分散キー - 列圧縮

などがあります。 これらについては以下で少し掘り下げて説明します。

Sort Key

テーブルをソートする際に使うインデックスのようなものです。 列単位で指定することができ、ORDER BYGROUP BY句などの精査速度に影響します。

分散キー

MySQLでいうパーティショニングキーに近いものとなります。

Redshiftのデータ分散方法は - 均等に分散 - キー値による分散 - 全コピー - Auto(負荷状況による自動選択)

の4つで、データ量や特性によって使い分けることが出来ます。

分散キーはRedshiftを上記の方法でクラスタリングした際に、どのノードにどのデータを保持するかを決定する判断材料となるキーです。

運用面の特徴

AWSコンソール

f:id:medley_inc:20190701165138p:plain RedshiftはAWSコンソール上からも詳細な情報を確認することが出来ます。

f:id:medley_inc:20190701165201p:plain Amazon RDSにあるような一般的なメトリクスに加えてクエリ単位での実行状況や実行計画、そしてクエリの強制停止もコンソールから実行することができます。

データ取り込み

Redshiftはインポート元となるデータ取り込み選択肢が豊富ということも特徴の一つです。

取り込み可能な形式

CSV/JSON/AVRO/PARQUET/ORC + これらの形式を圧縮したもの(BZIP,GZIPなど)

読み取り元

Amazon S3/Amazon EMR/Amazon DynamoDBなど

特にデータ配置元としてS3がサポートされているので、各種サービスが出力するログや、Amazon CloudWatch LogsからのS3やAmazon Kinesis Data FirehoseからのS3・・など、組み合わせ次第で可能性がとても広がります。

またS3に配置しているデータはインポートせずに外部テーブルとして直接クエリを実行する機能Amazon Redshift Spectrumがあります。データ量がとても多い場合などにはこちらを利用するのも有効な手段です。

ワークロード管理

f:id:medley_inc:20190701165215p:plain 負荷に関する運用についてはWLM(Work Load Management)という機能があります。

これはRedshiftに接続するユーザをグループ単位で負荷制御を行うことが出来る機能です。

制御できる項目としては

並列クエリ実行数

同一グループ内でのクエリ同時実行数。上限に達すると待ち行列に入って詰まる。

クエリ実行時間

クエリ実行時間の上限。

メモリ使用量

クエリ実行時に使うメモリ使用量の上限。

などがあります。

可用性について

Redshiftはクラスタリングをサポートしており、クラスタにはクエリの待受を行うリーダー(Leader)ノードと実処理を行うコンピューティングノードが作成されます。

AWSも推奨しているように、Redshiftはマルチノード運用を基本としています。

これはRedshiftの個々のデータノードはRAID5のような形で各ノードに分散しているため、ノード障害が発生した場合でも生存ノードからノード復旧を自動で行ってくれます。 (同時に障害が発生しても復旧可能なノード数については、クラスタ内のノード数に依存します)

将来性について

過去1年半の間でもこれだけの新機能が追加されており、まだまだ進化しています。

  • UNLOADコマンドのCSV対応
  • Concurrency Scaling
  • ALTER文でVARCHARの桁数変更
  • Elastic Resize
  • UNLOADコマンドのヘッダ行出力対応
  • コンソールにてクエリ実行環境追加
  • ネスト化されたデータのサポート
  • 自動バージョンアップ方式の設定/予告確認可能
  • Parquet、ORCからのIMPORTサポート
  • Amazon Redshift Spectrum東京サポート
  • 新ノードタイプDC2
  • Query Editorの追加
  • PL/SQL プロシージャのサポート
  • Vacumコマンドの自動化 New!!(2018/12リリース)
  • WLMワークロード管理の自動化 New!!(2019/06リリース)

実際の使い勝手

では、実際のところRedshiftの使い勝手がどういったものなのかを実例を含めて紹介します。 ここではdc2.large ノード数2のサンプル環境を使用します。

データのロード

クエリを発行するにも、まずは元になるデータが必要です。

ここでは日本語Wikipediaの目次ダンプデータを100セット分用意し、その内容をRedshiftにロードしてみます。

f:id:medley_inc:20190701165252p:plain f:id:medley_inc:20190701165257p:plain まずは目次データをこちらの画像の様に加工し、100セット分のファイルとして分割しS3へとアップロードします。

f:id:medley_inc:20190701165317p:plain 今回のロードするデータ量は235,732,000レコードの11.9GBとなりました。

f:id:medley_inc:20190701165331p:plain S3にファイルが配置出来たら、それを格納するテーブルをRedshiftに作ります。 この際PostgreSQLCREATE TABLEによってテーブルを作成します。

f:id:medley_inc:20190701165355p:plain テーブルの作成が完了したら、次はデータのロードです。 これもSQLクエリのCOPYコマンドによって取り込みが行われます。 今回このロード処理は8分55秒で完了しました。

データ量から考えるとかなり早いと感じますが、これはロード処理において並列処理の恩恵を最大限に受けているということが理由と考えられます。

Redshiftのロード処理は分割されたファイルを使って並列処理を実行するため、巨大な単一ファイルを取り込むより短時間で取り込むことができます。

クエリ発行

次に、クエリ発行についてですが、これはそのままPostgreSQLのクエリを実行することになります。

今回は先のステップで取り込んだ目次ページをタイトルごとにDISTINCTする集計クエリを発行してみます。

f:id:medley_inc:20190701165409p:plain すると49秒で結果が帰ってきました。 最低限のスペックで235,732,000レコードを精査するクエリの実行時間としては良いスコアではないでしょうか。

不便に感じたこと

ここでは私がRedshiftを運用していて不便に感じた事をいくつか紹介します。

料金が高い

これだけの機能とスペックが含まれているので仕方が無いかもしれませんが、AWSの他のサービスと比較して高価な印象があります。

さらにマルチノードとなると料金が掛け算で増えることになり、スペックの選択肢が他のサービスと比べても少ないため運用の際にはよく見積もりされることをおすすめします。

更新クエリが遅い

列志向型のせいなのかランダムアクセスが苦手で、特定の行を探して更新するUPDATEDELETEは遅いです。

そもそもRedshiftは頻繁にUPDATE/DELETEする用途には向いておらず(後述)、INSERTのみの積み上げ型や全レコード洗い替えが基本の用途になります。

また、UPDATE/DELETEを繰り返すとパフォーマンスが低下します。

これは内部的に保持しているSortKeyの状態が更新するたびに劣化し、連動してパフォーマンスが低下するためです。

解消するためにはSortKeyの再構築(VACUM/OPTIMIZEコマンド)により回復しますが、そもそもコマンド実行時間が長く、負荷も大きいので実行タイミングは検討が必要となります。

(追記)2018/12のアップデートで自動実行機能が追加されました!

AWSコンソールが機能しないことがある

先に多くの便利な機能を紹介しましたが、なぜかこれらがAWSコンソール上で機能してくれないことが割とあります。

WLMの設定次第なのか不明ですが、実行中のクエリが出なかったりクエリの強制停止が効かないなど、イザという時に限って使えないことがよくありました。

メンテナンスが高頻度

新機能が続々追加されていると紹介していますが、この度にメンテナンスが発生するものとなります。

タイミングは事前に設定したメンテナンスウインドウの週一の曜日/時間帯ですが、経験から2週間に1度ぐらいの頻度で発生していました。

この時間帯は再起動を伴う場合もあるため、WriteどころかReadすら出来ない状態になることもあります。

そのため日中は社内業務。夜間はバッチでといった24時間ずっと稼働する要件を満たす事は少し厳しいものとなります。

まとめ

まとめととなりますが、Redshiftは特徴をふまえると下記のような場面で利用すれば良いかなと感じています。

BIツール等のデータソースとして

メンテ頻度や負荷の問題があるので、自分達のアプリから直接は繋げない。

履歴やマスタデータのような大量の積み上げ型データの集計

UPDATEが発生するなら、全件入れ替えが可能なデータ。

1日の利用頻度がそれなりにあること

頻度が高く無いのであれば、Athenaの方が安い。

どのサービスにも言えることですが、要件の合ったサービス選びをすることが一番大事です。

Redshiftについても特徴がはっきりしているタイプのサービスなので、使い所を間違えないように、上手く使っていければと思います。

メドレーが協賛予定のイベントをご紹介します。(2019/7~)

こんにちは。開発本部エンジニアの平木です。

メドレーでは、技術や業界の発展に少しでも寄与できればという考えから、エンジニア・デザイナーの技術イベントなどに、積極的に協賛させていただきたいと考えています。7月以降のイベントも積極的にスポンサードさせていただきますので、ぜひ皆様にもお越しいただきたく、このエントリではメドレーが協賛するイベントの魅力をご紹介します。

Developers Summit 2019 Summer

f:id:medley_inc:20190620190529p:plain

  • 公式サイト
  • 2019/07/02(火) @ソラシティカンファレンスセンター
  • ブロンズスポンサー

一番最初にご紹介するのは、ご存知Developers Summit 2019 Summer(以降デブサミ夏)です。

本家であるDevelopers Summit 2019冬でも協賛させていただきましたが、今回のデブサミ夏ではブロンズスポンサーとして執行役員である田中SI × Webの総合力で切り拓く新しいエンジニアのキャリアパスというタイトルでお話します。

ここ数年でX-TechDXの必要性が一気に叫ばれるようになってきましたが、メドレーでも医療におけるデジタルトランスフォーメーションの推進を目指して日々プロダクトの開発を進めています。X-TechやDXを推進する上で、いわゆる「Web系エンジニア」と「SI系エンジニア」という垣根を越えた、ハイブリッドな新しいエンジニア像が求められるようになってきたと感じます。「課題を解決するために必要とされるようになったハイブリットな能力とは?」「これからのエンジニアはどう成長していくのがよいか?」ということをお話させていただきます。

おかげさまで、現時点でセッションは満員になっていますが、ぜひご覧いただければ幸いです。

CloudNativeDays Tokyo 2019 / OpenStack Days Tokyo 2019

f:id:medley_inc:20190620190716p:plain

今年はイベントの統合もされ、名称も一新された日本最大級のコンテナ技術を始めとしたクラウドネイティブとオープンインフラの祭典である、こちらのイベントにも協賛させていただきます。

当日会場で配られるトートバッグに公式ロゴと共にメドレーのロゴを入れていただきました。実際にどんなデザインになるかは当日にご来場していただくまでのお楽しみとさせていただきますが、とても良いものになっているかと思います。

builderscon tokyo 2019

f:id:medley_inc:20190620190740p:plain

2016年から毎年開催されている、色々な分野のエンジニアの様々なセッションが一気に聞けるイベント「builderscon tokyo」ですが(去年は電子名札バッジがインパクトありましたね)、今年は初めてスポンサーとして参加させていただくことになりました。

会場である東京電機大学千住キャンパスの部屋の一つ、100周年記念ホールでセッションするスピーカーさんの後ろに設置されるバックパネルのなかに、メドレーのロゴが入ることに。

こちらのイベントでは弊社エンジニアもお邪魔する予定ですので、会場でお気軽にお声がけしていただければと思います。

CODE BLUE 2019

f:id:medley_inc:20190620190759p:plain

今年で7回目の開催となる情報セキュリティの国際会議「CODE BLUE 2019」に初めてスポンサーをさせていただいています。

メドレーでも取り扱っている情報の重要性から、会社としての取り組みでISMS認証 / ISMSクラウドセキュリティ認証を取得していますが、このようなセキュリティに関するイベントにも業界の発展に少しでも寄与できればと今年から協賛させていただくことになりました。

DesginShip 2019

f:id:medley_inc:20190620190818p:plain

去年から開催されているデザインカンファレンス「DesignShip 2019」に、去年から続きスポンサーをさせていただきます。

今年は会場も東京国際フォーラムになるということで、メドレーも去年よりもさらにアクティブな形でイベントに参加させていただくことになりそうです。

まとめ

ここまでご紹介させていただいたイベント以外にも現在、スポンサーの打診をさせていただいているイベントがいくつかありますが、こちらも決定次第おしらせできればと考えています。

メドレーでは、技術や業界の発展に少しでも寄与できればという考えから、エンジニア・デザイナーの技術イベントなどにこれからも積極的に協賛させていただくスタンスを取っています。

全てのイベントに協賛できるわけではありませんが、スポンサーを探しているイベント運営者の方がいらっしゃいましたら、一度お気軽にお問い合わせいただければと思いますので、よろしくお願いします。

▼メドレーってどんな会社?気になった方はこちら www.medley.jp

ユーザー認証とOpenID Connect

こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会TechLunchの内容をご紹介させていただきます。

イントロ

Webサービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Webサービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。

 

また最近では、Amazon CognitoFirebase AuthenticationAuth0など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みをAmazon Cognitoにまかせてシステムを構築したことがありました。

しかし、当時は特にユーザープールの機能がリリースされて間もないこともあり、SDKの動作やサービスの仕様の理解にかなり手間取ったことを覚えています。

ユーザー認証サービスではOpenID Connectという仕様に準拠していることが多いのですが、おそらく自分にとってこの仕様の理解が疎かだったことが原因の一つだったと思います。

 

そこで今回は、ユーザー認証とOpenID Connectの仕組みについて改めて勉強し直したので、その内容を簡単に解説をさせていただこうと思います。

ユーザー認証とは

ユーザー認証の前に、そもそも認証とはどういう操作のことを指すのでしょうか。 みんな大好きWikipedia先生によると、以下のような記載があります。

 

認証(にんしょう)とは、何かによって、対象の正当性を確認する行為を指す。 認証行為は認証対象よって分類され、認証対象が人間である場合には相手認証(本人認証)、メッセージである場合にはメッセージ認証、時刻の場合には時刻認証と呼ぶ。 単に認証と言った場合には相手認証を指す場合が多い。

 

ユーザー認証はWebサービスにとってリクエストを送信してきた相手の正当性を認証することなので、相手認証の1つですね。 さらに相手認証の認証方法として2通りの方法があります。

 

第1の方法は、被認証者が認証者に、秘密鍵をもっていることによって得られる何らかの能力の証明を行う方法である。第2の方法は、被認証者が認証者に、被認証者の公開鍵に対応する秘密鍵の知識の証明を行う方法である。

 

ユーザー認証の場合、多くはこの第1の方法での認証で、ログイン時にユーザーIDに加えて、この「秘密鍵」としてアカウント作成時に登録しておいたパスワードを入力することでユーザー認証を行っているかと思います。

Webサービスでのユーザー認証

Webサービスで扱う情報の秘匿性が高くなればなるほど、この「秘密鍵」が本当にそのユーザーにしか提供できない情報であることが求められます。

上述のようなパスワードによる認証の場合、パスワードが推測されるなどして悪意のある第三者にアカウントが乗っ取られてしまう事件はよく耳にします。

よりセキュリティを高めるため、パスワード以外の認証や多要素認証などを用いる事が増えてきました。

 

また、セキュリティの観点だけでなく利便性の観点からも、パスワード入力の代わりに指紋認証や顔認証によるログインや、あるいは各種SNSアカウントによるログインも増えてきています。自社の複数のサービスを連携できるようユーザーに共通IDを提供したい、といったケースもあるかもしれません。

 

最近ではパスワードレス認証やWebAuthnも注目されていますね。今回は紹介は割愛しますが、パスワードレス認証の一つであるFIDO認証は、前述の「被認証者が認証者に、被認証者の公開鍵に対応する秘密鍵の知識の証明を行う方法」を利用した認証方式のようです。(ref1, ref2

 

このように、セキュリティの観点やユーザー利便性の観点などにより、Webサービスにおけるユーザー認証機能は1回作ったら終わりではなく、時流に応じて適宜改修する必要が出てくることもあるかと思います。

 

しかし、特にユーザー認証がメインのサービスと密結合している場合などでは、認証の前後など認証処理そのものだけでなくその周辺の処理への影響範囲も無視できない場合もあり、ユーザー認証の改修に工数が思ったよりかかってしまったり、対応が滞ってしまうこともあるかもしれません。

 

そんなとき、認証サービスをメインのサービスと切り離すことでより柔軟なユーザー認証手段を提供できるよう、OpenID Connectの導入を検討してみても良いかもしれません。

OpenID Connectとは

OpenID Connect(以降、OIDC)について、本家サイトでは以下のように説明されています。

 

OpenID Connect 1.0 は, OAuth 2.0 プロトコルの上にシンプルなアイデンティティレイヤーを付与したものである. このプロトコルは Client が Authorization Server の認証結果に基づいて End-User のアイデンティティを検証可能にする. また同時に End-User の必要最低限のプロフィール情報を, 相互運用可能かつ RESTful な形で取得することも可能にする.

この仕様は, OpenID Connect の主要な機能である OAuth 2.0 上で End-User の情報伝達のためにクレームを用いる認証機能を定義する. この仕様はまた, OpenID Connect を利用するための Security, Privacy Considerations を説明する.

 

日本語, 英語

 

個人的には、メインのサービスと認証サービスを切り離して運用することを想定して仕様が規定されている点が重要と考えます。 OIDCを利用することで、ユーザー認証をより柔軟に改修したり新しい認証方法に対応したりすることがしやすくなることが期待されるからです。

 

なお、OIDCの仕様には認証手段自体(パスワード認証や多要素認証など)に関しては規定されておらず、あくまで認証サービスによる認証結果の取得方法や扱い方についてが規定されています。

また、様々なユースケースに対応できるよういくつかの処理フローやオプショナルな設定が提供されていますが、その反面セキュリティの確保は実装者に委ねられており、ユースケースに応じて適切な実装を行う必要があります。

 

前述したユーザー認証サービスであるAmazon CognitoやFirebaseAuthenticationなどは、認証手段が標準でいくつか提供されており、加えてバックエンドとSDKにOIDC固有のセキュアな実装が施されてあるため、開発者は最小限の設定だけでユーザー認証機能が利用できるようになります。便利ですね。

処理フローの解説

さて、OIDCの具体的な処理について解説していこうと思います。


まず登場人物です。

  • OpenID Provider(OP):認証認可を行うサービス。ユーザー認証情報(識別子やパスワードなど)を管理したり、認証に関するユーザー属性情報(氏名やユーザー名など)を保持する。
  • RelyingParty(RP): アクセス元のユーザーの認証とユーザー属性情報を要求するサービス。ユーザーからのリクエストに対しOPによる認証結果を信頼(rely)してリソースへのアクセスを許可する(例えばマイページを表示するなど)。
  • EndUser:ログインをしてサービスを利用しようとしているユーザー。

 

基本的な用語も先に簡単に紹介しておきます。

  • クライアントID:OpenID Providerで管理する、RelyingPartyの識別情報。
  • クライアントシークレット:OpenID ProviderがRelyingPartyごとに発行する秘密鍵
  • 認証コード:後述するAuthorizationCodeFlowでOpenID Providerが発行する短命のパスワードのようなもの。
  • IDトークン:OpenID Providerから発行される、ユーザーによる認証を行った証明情報。JSON Web Token(JWT)で表現され、検証により改ざん検知することができる。認証の内容(OpenID Provider、ユーザー識別子、RelyingPartyのクライアントID、有効期限など)やユーザー属性情報が格納される。
  • アクセストークン:OpenID Providerが保持するユーザー属性情報に対しアクセスするためのOAuth2の認可トークン。

OIDCの処理フローは大きく分けて3種類が規定されています。

  • AuthorizationCodeFlow:認証成功時にOpenID ProviderがRelyingPartyに対し認証コードを発行し、RelyingPartyはこれを用いてOpenID ProviderからIDトークン等を取得する。RelyingPartyがサーバーサイドアプリケーションで、OpenID Providerから発行されるクライアントシークレットを安全に管理することができる場合などに用いられる。
  • ImplicitFlow:認証コードを使わず認証結果のレスポンスでIDトークン等を取得する。RelyingPartyがクライアントアプリケーションの場合など、クライアントシークレットが安全に管理できない場合などに用いられる。
  • HybridFlow:AuthorizationCodeFlowとImplicitFlowの組み合わせ。

これらのフローの違いは以下の表のとおりです。

 

f:id:medley_inc:20190426141901p:plain

公式より引用

 

今回は、公式こちらの解説記事などを参照しながら、基本の処理フローであるAuthorizationCodeFlowについて解説します。

 

簡略化のため、イメージ重視で登場人物は「ユーザー」「(ユーザーにサービスを提供する)Webサービス」「認証サービス」と表現することにします。

f:id:medley_inc:20190426141939p:plain

大まかには以下のステップで処理が行われます。

  1. ユーザーからのアクセスに対し、Webサービス認証サービスにユーザー認証を要求する
  2. 認証サービスはユーザー認証を行い、認証コードを発行して、ユーザーWebサービスにリダイレクトさせる
  3. Webサービスは2で取得した認証コードを用いて認証サービスにIDトークン等をリクエストする
  4. Webサービスは3で取得したIDトークンを検証し、ユーザーの識別子を取得する

Step.0 : 事前準備

あらかじめWebサービス認証サービスからクライアントIDとクライアントシークレットを取得し保持しておきます。

f:id:medley_inc:20190426142007p:plain

Step.1: ユーザー認証の要求

ユーザーWebサービスに対し一般的なログインの流れでログインを要求すると、Webサービス認証サービスにリクエストをリダイレクトします。

f:id:medley_inc:20190426142502p:plain

Webサービスから認証サービスへのリダイレクトのURLは以下のような感じです。

HTTP/1.1 302 Found
Location: https://server.example.com/authorize?
   response_type=code
   &client_id=s6BhdRkqt3
   &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
   &scope=openid%20profile
   &state=af0ifjsldkj

 

response_type でOIDCのどの認証フローを使うかを指定します。

redirect_uri は、認証サービスでの認証が成功したときのWebサービスにコールバックするURLです。これは事前に認証サービスに登録しておく必要があります。

scopeには認証の内容を設定します。openidは必須で、他にはOAuth2のアクセストークンを使って取得できるユーザー属性情報を指定します。

scopeで指定できるユーザー属性情報は以下のとおりです。

 

f:id:medley_inc:20190426142232p:plain

公式より引用

 

ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。

 

state はCSRF対策などのためのランダム値です。認証フローを開始するたびにWebサービスが発行し、リクエストとコールバックの間で値が維持されます。

 

他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。

Step.2: ユーザー認証と認証コードの発行

認証サービスでは認証手段に応じてログインID・パスワードの入力フォームなどを表示し、ユーザーから認証情報を取得して認証処理を行います。

f:id:medley_inc:20190426142212p:plain

認証サービスはユーザーの認証に成功すると、認証コードを発行し、ユーザーWebサービスにリダイレクトさせます。

 

HTTP/1.1 302 Found
Location: https://client.example.org/cb?
   code=SplxlOBeZQQYbYS6WxSbIA
   &state=af0ifjsldkj

 

リダイレクト先について、認証サービスはStep.1で受け取った redirect_url を認証サービスに予め登録されているURLと合致することを検証する必要があります。Webサービスのなりすましを防ぐためです。

またWebサービス側で認証サービスからのレスポンスであることを確認できるよう、state もパラメータに含めます。

 

なお、認証に失敗した場合は下記のように認証エラーした内容をパラメーターに加えてWebサービスにリダイレクトさせます。

HTTP/1.1 302 Found
Location: https://client.example.org/cb?
   error=invalid_request
   &error_description=
     Unsupported%20response_type%20value
   &state=af0ifjsldkj

Step.3: 認証結果の取得

Step.2 でWebサービス認証サービスからのリダイレクトを受け、認証コードを取得すると、この認証コードを利用して認証サービスに対して認証結果情報(IDトークンなど)を取得します。

f:id:medley_inc:20190426142612p:plain

Webサービスから認証サービスへの認証結果取得リクエストは以下のような形式になります。

 

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
 
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
  &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

 

認証コードを送信する必要があるため、POST メソッドでリクエストします。またクライアントIDとクライアントシークレットによるBASIC認証を行います。

このリクエストでクライアントシークレットが必要になるのですが、これは認証サービスにとってWebサービスの正当性を検証するための重要なパラメータであり、安全に管理される必要があります。

SinglePageApplicationのようにユーザー側にあるアプリケーションでOIDCを処理する場合には、このクライアントシークレットが安全に管理される保証がないため、AuthenticationCodeFlowではなくImplicitFlowなどを利用する必要があります。

 

Webサービスからのリクエストを受け取った認証サービスは grant_type にStep.1で指定した処理フローに該当する情報を渡し、認証コード( code )と合わせて認証サービスにリクエストの検証をさせます。

認証サービスはリクエストの検証に成功すると、Webサービスに対し認証結果としてIDトークン等を返却します。

 

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
Pragma: no-cache
 
 {
  "access_token":"SlAV32hkKG",
  "token_type":"Bearer",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "id_token":"eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso"
 }

 

access_token は認証サービスで管理しているユーザー属性情報を取得するためのOAuth2トークンです。

refresh_tokenは認証サービスからaccess_tokenを再発行する際に利用します。

Step.4: 認証結果の検証

Webサービス認証サービスから取得したIDトークンを検証します。IDトークンは前述の通りJWTで表現されており、認証サービスの公開鍵を用いて検証することができます。

手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。

下記はIDトークンに含まれる認証情報の例です。

 

{
  "iss": "https://server.example.com",
  "sub": "24400320",
  "aud": "s6BhdRkqt3",
  "exp": 1311281970,
  "iat": 1311280970
}

 

このうち sub が認証サービスで管理されているユーザーの識別子です。

iss認証サービス、audはWebサービスのクライアントIDになります。

exp、iatはそれぞれ認証の有効期限と認証したタイムスタンプです。

 

WebサービスはIDトークンが正しい内容であることが確認できれば、これをログインセッションと紐づけて保管します。

以上で認証処理は完了です。

ユーザー属性情報の取得

ユーザー認証後、Webサービスがユーザー名などのユーザー属性情報が必要になった場合、Step.3 で取得した access_token を利用し認証サービスに対してユーザー属性情報をリクエストします。

 

GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG

 

このリクエストにより、Step.1の scope で指定したユーザー属性情報が取得できます。

まとめ

以上少し長くなりましたが、ユーザー認証とOpenID Connect、特に基本のAuthenticationCodeFlowについて解説しました。限られた発表時間の中での解説のため厳密さより雰囲気を重視した内容となりましたが、お気づきの点などあればお知らせいただければと思います。

 

サービスの要件やフェーズによってOIDCを取り入れるかどうかは様々ですが、ユーザー認証の実装を自前で実装、メンテナンスしていくだけでなく、Amazon Cognitoなどの便利な認証サービスを利用していくことも選択肢の一つとして検討してみても良いかもしれません。

 

そしてそれら便利な認証サービスをうまく使いこなすためにも、その背景にあるOIDCの仕様や思想、そもそも認証の仕組みについて立ち返ってみると、理解が一段と深まるかとおもいます。

www.medley.jp

www.medley.jp

RubyKaigi 2019にメドレーがBreakfast Sponsorとして参加しました

こんにちは。開発本部のエンジニア・新居です。

メドレーは4/18〜4/20に開催されたRubyKaigi 2019にBreakfast Sponsor(朝食スポンサー)として協賛させていただきました(一昨年のRuby Sponsor昨年のLightning Talks Sponsorに続き、3年目の協賛です)。
2017年のレポート
2018年のレポート
2019年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそくRubyKaigiのポスターに迎えられ、RubyKaigiムードが高まっておりました。

RubyKaigi

博多駅ではさっそくRubyKaigiのポスターがお出迎え
ということで、今年RubyKaigiの様子をレポートさせていただきます。

Breakfast Sponsorの様子

今回はBreakfast Sponsorとしての協賛で、RubyKaigi2日目と3日目の朝8時30分から10時までの時間帯で、RubyKaigiに参加されるみなさんに朝食をご提供させていただきました。
 
朝食会場は福岡国際会議場内の1Fにあるレストラン ラコンテさん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。

入り口でみなさんをお出迎えするエンジニア稲本

おしゃれなテラス席

ビュッフェに並ぶおかず

フルーツもたくさん

「辛子明太 & 辛子高菜」乗せごはん

福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました

会場の様子、大盛況でした

テラス席はグローバルな感じ


Twitterでも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。
ご来場いただいた人数は、RubyKaigi2日目(朝食1日目)は379名、3日目(朝食2日目)は411名でした。
 
朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。
 
Breakfast Sponsorでの参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。
 
朝食をご利用いただいたみなさん、本当にありがとうございました。
 
今年はBreakfast Sponsorという形でしたが、RubyRubyコミュニティの発展のため、今後も様々な形で貢献していければと思います。

RubyKaigi 2019の様子

今年も毎年恒例のMatzさんのKeynoteから始まりました。
今年は「The Year of Concurrency」というテーマで、Ruby 3についての発表でした。
 
Ruby 3のStatic Analysis、Performance、Concurrencyあたりの話を中心に、Rubyの今後の展望について語られました。普段Rubyを使って仕事をしている身として、MatzさんからRuby 3の話を聞けたのは貴重な時間でしたし、改めてRubyの進化を実感できるセッションでした。

MatzさんのKeynote

その他のセッションスケジュールについてはこちら。

2階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。

ブースゾーンは大盛況

ブースゾーンの出入り口付近には各社のノベルティ

Ruby関連書籍の展示も

会場5階(最上階)にはハックスペースが用意されていました。
ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。

ハックスペース入り口

ハックスペースの中(このときはセッション中だったので空いてました)

福岡開催ならではの屋台スペースも用意されていました。
ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しはRubyKaigiを盛り上げてくれるので良いですね。

ランチ前になるとゾロゾロと人集りが

ランチタイムの屋台は大行列

屋台でラーメンを食らう参加者を羨むエンジニア中畑


メドレーブースの様子

また、2階のブースゾーンにはメドレーのブースも出展しました。

今回参加したメンバー全員で
ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。
 
RubyKaigi 2018でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。
靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。

メドレーの絆創膏
ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。
 
スポンサーとして初参加だったRubyKaigi 2017に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました

ブースで対応するエンジニア達(中畑、稲本、橋本)

Matzさんにも来ていただきました!

福岡の様子

そして福岡といえば美味しいごはんですよね。
 
1日目の夜はRubyKaigi 2019 Official Partyが開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。

RubyKaigi 2019 Official Partyの会場・中洲川端商店街のGuide Map

大樽に入って日本酒が配られてました

日本酒のラインナップ

f:id:medley_inc:20190424143021j:plain

うどんを前に満面の笑みの広報・深澤

夜は福岡の美食を求めて街に繰り出しました。

絶品イカの活造り

定番モツ鍋

出汁が最高の水炊き

会場近くの某有名ラーメン店のきくらげラーメン

あまりのうまさに昇天するエンジニア中畑

また、RubyKaigi初参加の2017年から続けている神社参拝にも行ってきました。
今回は警固神社(けごじんじゃ)に参拝してきました。
 

警固神社入り口

参拝するエンジニア中畑


さいごに

2017年から3度目となるRubyKaigiの協賛の様子をお届けしました。
 
Breakfast Sponsorとして、RubyKaigi参加者のみなさんにご満足いただけて本当に良かったなあと思います。
繰り返しになりますが、RubyRubyコミュニティの発展のため、今後も様々な形で貢献していければと思います。
 
来年2020年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。

rubykaigi.org

お知らせ

メドレーでは医療業界に存在する課題にITを駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。

www.medley.jp

RubyKaigi 2019に朝食スポンサーとして協賛します

みなさん、こんにちは。開発本部の平木です。

2017年から、RubyKaigiにスポンサーとして参加していましたが、今年も朝食スポンサーとして協賛することになりました! f:id:medley_inc:20190412183606p:plain

(去年とおととしの参加レポート)

developer.medley.jp

developer.medley.jp

会場である、福岡国際会議場内の1Fにあるレストラン ラコンテさんでビュッフェ形式の朝食を楽しむことができます。

会期中の4/19~20日の8:30 ~ 10:00で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。

f:id:medley_inc:20190412183045j:plain

メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。

また、スポンサーブース内にもメドレーブースが常設されており、エンジニア4人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。

それでは、RubyKaigiという大きなイベントでまた皆様にお会いできるのを楽しみにしています!!

電子処方箋実証事業におけるFHIRの活用と標準化の展望

こんにちは。CLINICS事業部の児玉です。

今回は、メドレーが2018年12月に厚生労働省から受託した「電子処方箋の本格運用に向けた実証事業」で、医療情報標準規格のFHIRを基盤とした電子処方箋管理システムを構築しましたので、その内容についてご紹介します。

FHIRとは

FHIR(Fast Healthcare Interoperability Resources)とは、医療情報交換の国際標準規格であるHL7(Health Level 7)の中で最も新しい規格であり、インターネットテクノロジーをベースとした、シンプルで効率的にシステム間での情報共有を可能にする「次世代の医療情報標準規格」として世界各国で注目されています。

HL7は、世界に30以上の国際支部を有しており、日本では1998年に日本HL7協会が設立されました。そして、現在流通しているHL7規格には、データ交換に利用されるHL7v2と、医用文書の記述に利用されるCDA(Clinical Document Architecture)が存在します。

電子処方箋とは

電子処方箋とは、従来の紙に印刷された処方箋ではなく、医療機関調剤薬局が電子データを用いて処方内容をやりとりする仕組みです。単純にペーパーレス化することだけが目的ではなく、患者個人の服薬履歴を電子的に管理して、重複投薬の適正化を図るといった目的もあります。

実証事業の背景と概略

2016年3月の法令改正で、処方箋の電子的な交付が可能となり、運用ガイドラインも策定されました。しかし、法令改正から数年が経過した現在においても、実運用での課題が払拭できずに、電子処方箋の全国的な普及は進んでおりません。

f:id:medley_inc:20190328142501p:plain
ガイドラインに定められた運用フロー(電子処方せんの運用ガイドラインより転載)

元来、処方箋には医師の記名押印、または署名が必要であると医師法で定められています。現行のガイドラインは、この規則を踏襲して設計されていますので、紙の処方箋の代替としてCDAで記述された静的ファイルを必要とし、記名押印の代替としてHPKIを使用した電子署名が必要となります。

また、クライアント端末で生成された静的ファイルが、インターネットに流通するフローとなっていますので、改ざんの検知を可能とするために電子タイムスタンプを付与する必要があります。

このように複雑化された運用フローが、電子処方箋の普及を阻害する要因の1つであると考えられます。

こうした状況を踏まえ、現行のガイドラインに縛られず、円滑な運用ができる仕組みを検討するために、実際の医療機関調剤薬局を使用したフィールド実験を実施しました。


実証事業概略

  • 実施目的:電子処方箋の運用の仕組みの検討・実証・考察
  • 実施期間:2019年2月4日 - 2019年3月17日
  • 実証エリア:東京都港区
  • 協力施設:2医療機関 / 6薬局
  • 利用実績:64件

電子処方箋管理システムの概要

以下に示すのは、今回の実証事業で開発した評価システムです。本システムは「処方箋管理システム」「医療機関システム」「薬局システム」「PHRアプリ」の4つのシステムから構成されています。

f:id:medley_inc:20190328140004p:plain
システム概観


  • 処方箋管理システム

    医療機関システム、薬局システム及びPHRアプリから接続され、各システムからの処理要求を受けて、処方データと調剤データの返答、作成、編集、及び削除を行う。

  • 医療機関システム

    診療結果としての処方データを処方箋管理システムに登録し、その結果として返される処方箋アクセスコードを患者に共有する。処方箋アクセスコードはQRコードの活用を想定し、QRコードを印字した紙又は電子データを患者に共有する。

*「QRコード」は株式会社デンソーウェーブの登録商標です。
  • 薬局システム

    訪問してきた患者の本人確認を行った上で、処方箋アクセスコードを受け取り、処方箋管理システムにアクセスし処方データを参照する。処方後は調剤データを処方箋管理システムに格納する。

  • PHRアプリ

    患者がオンライン診療やお薬手帳の機能を利用するためのアプリ。処方箋管理システムへのアクセスが許可され、医療機関システムから受け取った処方箋アクセスコードを元に、調剤結果を参照することを可能にする。


医療機関システムは、メドレーのクラウド電子カルテ「CLINICSカルテ」を利用しましたが、システム連携に関わる部分については、他の電子カルテなどでも活用できるよう、疎に結合した設計を意識しました。

処方箋管理システムは、前述の通りFHIRインターフェイスを基盤として構築しました。これは現行のガイドラインには記載されていない新たな試みです。

HPKIを利用したSSO(Single Sign On)による本人資格確認と、FHIRインターフェイスを利用したクラウドベースでのデータフローを実現することが可能であれば、複雑化の要因となっている静的ファイル、電子署名、タイムスタンプは不要であると考えました。

データ設計

FHIRには「リソース」と呼ばれるデータセットが定められています。リソースは、Patient(患者)、Practitioner(施術者)、Organization(組織)といった粒度で設計されており、リソース単位でのデータ交換が可能です。

FHIRを利用するためには、その目的に応じたリソースの選定と、リソースの下位概念であるフィールドに設定する具体的な値を定義する必要があります。

例えば、日本では人名を記述する際に、漢字氏名とカナ氏名を併記することが一般的ですが、グローバル・スタンダードではありません。このような国の事情に応じて、ローカライズされた記述ルールを定める必要があります。

実証事業で使用したリソース

リソース 説明
Patient 患者
Practitioner 施術者(処方医/薬剤師)
PractitionerRole 施術者役割
Organization 組織(医療機関調剤薬局
MedicationRequest 投薬要求
MedicationDispense 調剤実施
Coverage 保険

FHIRを使用した所感

FHIRの改版はon-Goingで行われています。実証事業のための開発を始めた頃は、STU3(Standard for Trial Use 3)が公式バージョンでした。しかし、あるとき急にFHIRのホームページが接続不安定になり困っていたところ、翌日にはR4(Release 4)に更新されていたということもありました。

このように、日進月歩のFHIRをプロダクトに組み込むには、タイミングの見極めと、アップデートに追従する「覚悟」を決めることが大切だと思います。

f:id:medley_inc:20190328210514p:plain
2018年12月27日にR4がCurrent Versionになりました

FHIRの利点は、従来のHL7規格と比較した実装容易性にあると考えます。REST(REpresentational State Transfer)のように、Webサービスでは一般的に普及している概念を標準として取り込んでいるため、実装者は特別な知識を習得する必要がありません。また、FHIRを実装するためのオープンソースライブラリが豊富に提供されており、これらを活用することによって、本当に必要な処理に注力して開発することが可能となります。

臨床概念モデルとしての観点では、CDAのベースとなっているHL7v3-RIM(Reference Information Model)と比較すると、クラス、継承のようなオブジェクト指向の概念が廃止されています。あらゆる臨床概念をモデリング可能とすることを目指したRIMと比べると、さすがに表現可能な範囲は狭まると思われますが、網羅性は実用域のレベルには達しているのではないでしょうか。

また、1:1のシステム連携におけるデータ交換では、すでに稼働しているv2インターフェイスを、無理してFHIRに置き換える必要は無いと思います。用途に応じて、既存の規格と共存していくのが大切であると考えます。

実運用へ向けての課題

FHIRリソースは、臨床概念としてユニバーサルに利用可能なものを中心に構成されています。保険情報のような各国の医療制度に応じて異なるものや、調剤技法に対する「一包化」や「粉砕」などの細かな指示情報に関しては、ある程度アドホックマッピングするしかありませんでした。実装者によるマッピングのブレが生じないようにするためには、指標となるガイドラインの策定が必要になります。

また、リソースにマッピングする医薬品や用法のマスターコードについては、厚生労働省標準マスターの利用が望まれます。しかしながら、満遍なく普及しているとは言い難い状況ですので、標準マスター利用の推奨も併せてガイドラインに明記することが必要です。

ガイドラインは、メドレー1社で策定することが可能なものではなく、医療情報システムの開発に関わる多くの開発者にFHIRを利用していただき、実装方法についての議論を交わす必要があります。しかし、現時点での日本国内におけるFHIRの活用事例は、残念ながらほとんど見られません。

次にご紹介するのは、FHIRを使用した簡単なコードのサンプルと、ローカル環境でFHIR Serverを簡易的に動かす方法です。実装者の方がFHIRに触れるきっかけになればと思って書きましたので、ご参考にしていただけますと幸いです。

FHIRの実装サンプル

FHIRを理解するためには、実際にコードを書いて動かしてみるのが一番だと思います。ここでは、ローカル環境でFHIR Serverを起動して、リソースを登録する簡単なプログラムを書いてみました。(オープンソースの恩恵を最大限に享受しています。)

実行環境

FHIR Server

DockerコンテナでFHIR Serverを起動します。簡単に動かせるように、DockerHubに公開されているHAPI-FHIRのコンテナイメージを利用します。

HAPI-FHIRとは、カナダのトロントにある医療研究機関のUHN(University Health Network)が立ち上げたプロジェクトで、FHIRのオープンソースライブラリを提供することを目的に活動しています。

Dockerコンテナイメージの取得

$ docker pull petersonjared/hapi-fhir
$ docker run -d -p 8080:8080 --name=fhir petersonjared/hapi-fhir:dstu3
$ docker exec -it fhir /docker-entrypoint.sh java -jar /usr/local/jetty/start.jar

Dockerをインストールするのが面倒な人は、HAPI-FHIRがグローバルに公開しているテストサーバーを利用することも可能です。ただし、世界中の人がテストに利用しているサーバーですので、機微な個人情報は登録しないよう注意が必要です。

FHIR Client

FHIR Clientは、Rubyで動かします。以下のGemを利用します。

$ gem install fhir_client
$ gem install fhir_models

Rubyのコードです。Patientリソースを作成してFHIR Serverに登録します。

patient.rb

require 'fhir_client'

client = FHIR::Client.new("http://localhost:8080/baseDstu3")
FHIR::Model.client = client
    
patient = FHIR::Patient.new

# 患者ID
identifier = FHIR::Identifier.new
identifier.value = '12345678'
patient.identifier = identifier
    
# 患者氏名
human_name = FHIR::HumanName.new
human_name.family = 'Kodama'
human_name.given = 'Yoshinori'
patient.name.push(human_name)

# 性別
patient.gender = 'male'

patient.create
puts patient.id

上記のコードを実行すると、FHIR ServerにPatientリソースが登録されます。ここでリソースを一意に特定するリソースIDが採番されます。今回は 19953 が採番されました。(puts patient.idで確認)

このリソースIDを利用して、FHIR ServerにHTTPリクエストを送ります。

$ curl http://localhost:8080/baseDstu3/Patient/19953

そうすると、先ほど登録したリソースがJSON形式で取得できます。

{
  "resourceType": "Patient",
  "id": "19953",
  "meta": {
    "versionId": "1",
    "lastUpdated": "2019-03-21T09:12:44.660+00:00"
  },
  "text": {
    "status": "generated",
    "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\">Yoshinori <b>KODAMA </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>12345678</td></tr></tbody></table></div>"
  },
  "identifier": [
    {
      "value": "12345678"
    }
  ],
  "name": [
    {
      "family": "Kodama",
      "given": [
        "Yoshinori"
      ]
    }
  ],
  "gender": "male"
}

もちろん、患者IDなど利用して検索することも可能です。

$ curl http://localhost:8080/baseDstu3/Patient?identifier=12345678

さいごに

今回の実証事業では、FHIRのインターフェイスを活用することにより、シンプルなアーキテクチャとシームレスなフローで、迅速に処方箋管理システムの構築ができ、電子処方箋の運用評価を行うことができました。本実証事業の最終成果報告書は厚生労働省のサイトに公開されていますので、詳細について興味のある方はこちらをご参照ください。

www.mhlw.go.jp

メドレーは、実証事業で得られた知見を可能な限りオープンにして電子処方箋の普及推進に取り組むことはもちろん、インターネットを活用したオープンな技術の普及活動に積極的に取り組み、医療機関と患者の双方にとってより良い医療の実現を目指してまいります。

お知らせ

今回の電子処方箋実証事業の成果と、システム開発に活用したFHIRについて共有するイベントを、以下のとおり4月23日(火)に開催します。お時間ある方はぜひご参加ください。

techplay.jp

また、メドレーでは医療業界に存在する課題にITを駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。

www.medley.jp