esm アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

RubyKaigi 2019 に今年もいっぱい参加します

もうすぐ RubyKaigi 2019 が福岡で開催されます。 今年も弊社からLT の登壇、 Night Cruise Sponsor、弊社メンバー 14 名が参加など様々関わり方しています。 RubyKaigi 2019 への関わり方をご紹介します。

Lightning Talks に @koic が登壇します

弊社 @koic が二日目の 17:20 から Main Hall で行われる Lightning Talks にて "The TracePoint Bomb!" というタイトルの発表をします。

Night Cruise Sponsor として協賛します

会期前日の 4/17 (水) に前夜祭として、夕方からクルーザーを貸し切って博多湾に出航する ESM Night Cruise at RubyKaigi 2019 を開催します。

出航する港は RubyKaigi 2019 の会場である福岡国際センターのすぐ近くです。 会場までの道順を予習しつつ、福岡の夜景を船上から眺めながら、翌日から始まる RubyKaigi に向けて交流を深めていただければと思っています。

残念ながら、海外の来場者枠、一般参加枠はすでにキャンセル待ちとなっています。 参加申込みを行っている方は出航時間に遅れないようご参加下さい。

スポンサーブースを出します

3Fメインホールホワイエ付近にてブースを出します。 ブースでは昨年好評だったプランニングポーカーを配布する予定になっています。 弊社や弊社メンバーに興味ある方はぜひ休憩時間などにお立ち寄り下さい。

学生を RubyKaigi に招待します

昨年に引き続き学生向け RubyKaigi 2019 招待ツアーを行います。 募集数を上回る多数のご応募をいただき、抽選で選出した二名の方を招待します。

この取り組みは新しく Ruby コミュニティに入ってくる方たちをサポートすることを目的として、 現役学生の方を対象に RubyKaigi 参加の費用補助を行います。

招待する二名の学生さんには参加レポートをどこかに書いていただくことになっています。 公開されましたら、またこちらのブログにて紹介できればと思います。

会社のサポートで14名参加します

チケット費、移動費、宿泊費など RubyKaigi に参加するために必要な費用は、会社から全額サポートされています。 参加するメンバーが中心となり、スポンサー内容のアイディア出しを行いました。

最後に

今年も RubyKaigi に様々な関わり方をします。 たくさんのメンバーが参加しますので、会場で見かけましたら仲良くしていただければと思います。

Ruby コミュニティにもっと関わっていきたいという仲間を弊社は待っています。 気になるという方は、是非ブースにて気軽にお声がけください。

Rails Developers Meetup 2019 への登壇とスポンサーのお知らせ

3月22日(金) から 3月23日(土) に渡って開催される Rails Developers Meetup 2019 に koic と takkanm が登壇し、日本酒スポンサーとして協賛します。

f:id:koic:20190320151714p:plain:w400

https://railsdm.github.io

Day 1: 会場 B 16:00 - 16:30 「Rails な受託の会社でぼくがやっていること」takkanm

Rails を使った受託会社で、takkanm が意識してやっていることを紹介します。

プロジェクトにどのように向かっているか、チームでの開発のとき何を意識しているか、新しくやってきた人に何を伝えているかなどを話します。

Rails な受託会社の一部をお見せできればと思います。

Day 2: 会場 A 12:30 - 13:00 「Ruby コミュニティの歩き方」koic

みんな大好き Ruby のコミュニティと、それに関係する (もしくはあまり関係しない) あれこれについて、ものすごくいい話。

🍶日本酒スポンサー

日本酒スポンサーとしてはハートビートセレクション*1の銘柄をそれぞれ Day 1 と Day 2 で用意する予定です。今回は Rails Developers Meetup 2019 懇親会立食用にセレクションしてもらいましたので、お楽しみください。

Day 1: 懇親会 20:00 - 22:30

  • モヒカン 一升
  • 天明一年熟成 一升
  • 長珍雄町生 一升
  • 会津娘さくら 四合
  • 残草QUEEN 四合
  • 田酒さくらラベル 四合
  • 福祝純大直汲み 四合
  • 能登そのまんま 四合
  • 旦純吟生28BY 四合
  • 奥播磨 四合

Day 2: 懇親会 19:00 - 21:30

  • 村祐亀口 一升
  • 南生 一升
  • 磐城甦 一升
  • 来福さくら 四合
  • 天穏春 四合
  • 春霞花ラベル 四合
  • 大盃マッチョ 四合
  • 宗玄しぼりたて 四合
  • 九平次生 四合
  • 奥播磨 四合

ESM からも多くのメンバーが参加します。当日お会いしましょう。

*1:和食 x Bar ハートビート https://www.instagram.com/heart_beatmaezo

2019 アジャイル事業部 年度始のご挨拶の会のご案内

f:id:E_Mattsan:20190220140254j:plain

もうすぐ新しい年度が始まります。みなさんどのようにお過ごしでしょうか。

恒例となりましたオブラブカレンダー、今回は4月始まりの2019年度版として完成しました。 各月にはメンバーが推す様々なテーマの内容が凝縮されています。

そしてカレンダーをお渡しする会を今回も開催することといたしました。

会ではカレンダーに書かれたテーマに沿った内容をメンバが LT で語ります。 簡単な軽食とお飲物を用意しておりますので、ご来場いただき LT と食事をひとときお楽しみいただけたらと思います。

そして今回は、平成最後のオブラブイベントでもあります。 オブラブやご自身が推すテーマについて語っていただくための来場者 LT 枠も用意いたしました。

開催は新年度を迎えた4月10日(水)の夜です。

ご参加を希望される方は申し込みページからご登録をお願いいたします。

あとひと月あまりで元号も改まります。

オブラブに縁のある方々も、初めてオブラブカレンダーを目にされる方々も、楽しんでいただける会にしたいと思います。

皆さんのご来場をお待ちしています。

今年も RubyKaigi 2019 に学生を招待します

昨年、仙台で開催された RubyKaigi 2018 にて、弊社としては初めて学生の支援を行いました。 学生支援を検討していた当初は利用してくれる人はいるのかなぁという気持ちがありましたが、 最終的にたくさんの学生からの応募があり、RubyKaigi に参加してみたいという学生は多いということを改めて認識しました。

そこで、福岡で開催される今年の RubyKaigi 2019 でも学生の支援を行います。 今年は、最大 2 名の学生を招待*1したいと考えております。支援を希望する学生は、以下の募集ページにある「キャンセル待ちに登録」から応募してください。

esminc.doorkeeper.jp

今年の RubyKaigi もたいへん内容の濃い RubyKaigi となっています。RubyKaigi は Ruby という技術やコミュニティについて世界で一番濃いイベントだと考えています。自分は初心者だからとか、そういったことで遠慮したりせず、是非応募してください。

このような取り組みを行っていて、かつ、社会人になっても RubyKaigi に参加ができる永和システムマネジメントでは、新卒、中途問わず、一緒に Ruby コミュニティの一員となってアジャイルな開発でお客様へ価値を届けることを目指す仲間を募集しております。

agile.esm.co.jp

*1:弊社の支援では、2020, 2021 に卒業見込みの 20 歳以上学生と制限させていただいておりますが、 Classi 株式会社 さんでは、博士、修士、学部、学年不問(高専生、高校生)のRubyKaigi2019_Classi Scholarship Sponsor という 支援を行われています。すでに応募者多数で抽選となっていますが、併せてご確認ください。

Rails / OSS パッチ会 2019年3月のお知らせ

コミュニティマネージャの koic です。

Rails / OSS パッチ会を 3月13日(水)に開催します。

この会をひとことでいうと、日頃のお仕事で使っている Rails をはじめとする OSS への upstream にパッチを送る会です。

会には RubyRails のコミッターである顧問の a_matsuda もいますので、例えば Rails に送るパッチのネタがあるけれど、パッチを送るに適しているかの判断やパッチを送る流れが悩ましいときなど a_matsuda に相談して足がかりにするなどできます。

以下、前回の活動が関わる成果です。

284km: CSV

github.com

autopp: OpenAPI Generator

github.com

colorbox: Warden

github.com

github.com

kamipo: Rails

github.com

koic: RuboCop

github.com

開催時間は 17:00-19:00 となりますがご都合のあう方はぜひご参加下さい。特に募集ページなど設けませんので、興味のある方は永和システムマネジメントの神田オフィスまでお越し下さい。

agile.esm.co.jp

Rails 6 Beta が出ていたり RailsConf 2019 を翌月に控えていることもあり、その動きに向けた話や終わった後は有志で懇親会などあるかもしれません。

f:id:koic:20190301131315j:plain:w400

Rails / OSS パッチ会 2019年2月のお知らせ

コミュニティマネージャの koic です。

Rails / OSS パッチ会を 2月28日(木)に開催します。

この会をひとことでいうと、日頃のお仕事で使っている Rails をはじめとする OSS への upstream にパッチを送る会です。

会には RubyRails のコミッターである顧問の a_matsuda もいますので、例えば Rails に送るパッチのネタがあるけれど、パッチを送るに適しているかの判断やパッチを送る流れが悩ましいときなど a_matsuda に相談して足がかりにするなどできます。

前回 2019年1月のパッチ会では、Rails 6 に向けた RDBMS ごとの処理系差異の議論など交えつつ盛り上がったりしました。

f:id:koic:20190128134351j:plain:w400

以下、前回の活動が関わる成果です。パッチに向けた設計議論が多めだったため会の時間帯で観測されたパッチは少なめです (私の見落としがいくつかありそう) 。

chiastolite: Rails

github.com

colorbox: Danger

github.com

colorbox: Rails

github.com

kamipo: Rails

github.com

開催時間は 17:00-19:00 となりますがご都合のあう方はぜひご参加下さい。特に募集ページなど設けませんので、興味のある方は永和システムマネジメントの神田オフィスまでお越し下さい。

agile.esm.co.jp

Rails 6 Beta が出ていることもあり、その動きに向けたディスカッションや、終わった後は有志で懇親会などあるかもしれません。

f:id:koic:20190128135143j:plain:w400

GraphQL でファイルをアップロードしたい

こんにちは、hibariya です。さいきん GraphQL でのファイルアップロード方法について知りたいなと思いちょっと検索してみたところ、すぐにはこれといった方法に辿りつけなかったので気になって調べました。手元で試した感じだと GraphQL multipart request specification という仕様が良さそうでしたので、今日はそのことについて紹介したいと思います。

GraphQL でのファイルアップロードはめんどう

現在のところ、GraphQL の仕様ではファイルアップロード方法については特に規定されていないため、自分たちで方法を決めて実装する必要があります。が、これは少し面倒です。HTTP で GraphQL を使う場合、サーバに渡す値はたいてい JSON のようなフォーマットでシリアライズしますが、FileオブジェクトはそのままJSONにはエンコードできません。

{
  "query": "mutation CreateMessage($input: CreateMessageInput!) { ... }",
  "variables": {"input": {"message": "hi", "file": "<アップロードしたい File をここに...??>"}}
}

ですから、GraphQL でファイルをアップロードしようというときには少し工夫が必要になります。方法としてよく挙げられているのは以下の3つでしょうか。

  1. ファイルを Base64 エンコードして JSON に含める
  2. ファイルのアップロードには GraphQL とは別の API を使う
  3. リクエストを multipart/form-data として送る

最初の方法1は、そのままではシリアライズできないファイルを Base64 エンコードすることで JSON として扱えるようにする方法です。クライアントとサーバ間の通信方法を大きく変える必要がなさそうで、シンプルそうに見えます。ただ、巨大なファイルを扱う場合には、あまり考えずにサーバ側のアプリケーションを実装すると巨大な JSON をオンメモリで扱うことになって面倒そうな気がします *1。あとはファイルサイズが若干増えますし、ファイル名のようなメタ情報を自分で渡さないといけないのも少し面倒ですね。

次の2はファイルアップロードを GraphQL API では扱わず、別途用意した REST API などを併用するという方法です。確かに方法のひとつとしては考えられますが、使い方によっては、元々ひとつだったトランザクションを分ける必要が出てくるなど用途を選びそうです。

最後の3は GraphQL のリクエストを multipart/form-data として送る方法です。ここで紹介する GraphQL multipart request specification は、この方法を採用しています。

GraphQL multipart request specification

リクエストに multipart/form-data を使う方法であれば、巨大なファイルは (例えば Ruby なら) Rack のレイヤで少しずつファイルに書き出される *2 ため、サーバサイドのメモリ使用量についての心配はひとまず置いておけます。また、この方法にはいくらか認知されている仕様として、GraphQL multipart request specification というものがあります。

仕様が定めているのは、multipart でどうやって GraphQL リクエストを送るのか、特に GraphQL の変数の値としてとしてどうやってファイルをマッピングするのかというところです。仕様そのものは単純なので、例をまじえて説明します。 README とほぼ同じですが、冒頭の例で説明するとクライアントは以下のような感じの multipart message をサーバに送ることになります。

--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="operations"

{
  "query": "mutation CreateMessage($input: CreateMessageInput!) { ... }",
  "variables": {"input": {"message": "hi", "file": null}}
}

--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="map"

{ "0": ["variables.file"] }

--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="0"; filename="hi.png"
Content-Type: image/png
Content-Transfer-Encoding: base64

(Base64 エンコード済みのファイル)

--------------------------cec8e8123c05ba25--

最初の part を見ると、operations というパラメータの中に GraphQL のクエリや変数が格納されています。ここは相変わらず JSON ですね。ところで肝心の変数 file (variables.input.file) が null となっています。これはtypo ではなくそういうもので、ファイル本体は別の part となっているため、サーバ側で適切にマッピングして、この null を上書きする必要があります。この例では、ファイルは最後の part にある hi.png です。真ん中には map というパラメータの part があります。これは、最初に登場した null と実際のファイルをマッピングするための情報です。この例の { "0": ["variables.file"] } でいうと「0 というパラメータは、variables.file の中身ですよ」といった意味になります。

サーバ側は、この仕様の実装がアプリケーションより下の層にあれば、アプリケーションを大きく変更することなくファイルのアップロードを実現できます。Ruby なら Rack のミドルウェアとして実装して、ファイルを params[:operations][:variables][:input][:file] で参照できるようにする、という具合です。

クライアント側も、変更が必要なのは主にネットワークレイヤになります。実装のひとつに Apollo Link のミドルウェアとしてこの機能を提供しているものがあるので、もし Apollo を使っているならそれを導入することで対応できるでしょう。残念ながら現時点では Relay (Modern) の実装として公開されているものは見当らないのですが、Relay の Network Layer をカスタマイズすることでなんとかなりそうです。Relay の方はちゃんと試してはいないので、知見をお持ちの方がいれば教えてください。

良さと注意点

現時点だと GraphQL でファイルをアップロードする方法としてはこの GraphQL multipart request specification が良さそうだと感じています。理由としては、まず仕様として公開されていて、既にいくつか実装があるということ。また、それらの実装を使うことで既存のアプリケーションの実装を大きく変えなくてもよいというのも良いですね。様々なクライアントに対応できるのが GraphQL の良さのひとつですので、Apollo/Relay どちらからでも使えるというのも重要なポイントだと思います。それから、私はよく Ruby を使うので Ruby の実装があるのも嬉しい。

注意が必要な点としては、あくまで multipart/form-data を前提にしているので、それに対応できないサーバやクライアントでは採用できません。

Ruby でのサーバ側実装

サーバサイドではどんな感じで導入すれば良いのでしょう。最後に GraphQL multipart request specification の Ruby のサーバサイド実装として jetruby/apollo_upload_server-ruby を紹介します。この gem が提供するのは次の2つです。

  • アップロードファイルを表現する Upload というスカラ型
  • GraphQL multipart request specification を実装した Rack middleware

Gemfile に足すと middleware が挿入されるので、基本的にはそれで導入は完了です。ただ、ひとつ注意点があります。このミドルウェアはファイルを ApolloUploadServer::Wrappers::UploadedFile として params に入れてくれるのですが、これは ActionDispatch::Http::UploadedFileDelegateClass でラップしたオブジェクトです。そのため、Active Storage にそのまま渡せないという問題があります (jetruby/apollo_upload_server-ruby#10)。私が手元で検証した際は、workaround として この comment のように IO とファイル名をひとつずつ渡しました。

おわりに

GraphQL でのファイルアップロードについて現状の私の理解を書きました。ここで紹介した GraphQL multipart request specification は、良さそうとは言いつつも、本格的な導入はまだ残念ながらできていません。知見をお持ちの方がいればぜひ教えてください。

もうすぐ大晦日ですね。よいお年を!

参考