Fast JSON API をつかって得た、JSON:APIの知見

もう話題になってから、2年くらいの月日がたってしまったと考えると、時の速さを感じます。
そんな時の速さと同じくらい、早くserializeできるというFast JSON APIをつかって、今年の前半期でサービスを作ったので、得た知見を残しておこうと想います。

ざっくりとした内容は、6月の表参道.rb で少し話させてもらいました！

[fast_jsonapi使ったぞ](https://speakerdeck.com/yoshixj/fast-jsonapishi-tutazo)

今回紹介するのは、fast_jsonapiをつかったRubyのコードの書き方というよりは、
fast_jsonapiに使われている、JSON:APIというフォーマットについて書こうと思います。

# 動機、経緯

新サービスのjsonを返す、APIをRailsで作ることになったので、serializerを選定してました。
以前のサービスは、jbuilderをつかっていたのですが、jsonの管理にとてもとても苦しい思いをしたので辞めました。
Railsのserializerを選定するとなった時、当時も現在も [AMS(active_model_serializers)](https://github.com/rails-api/active_model_serializers) か [fast_jsonapi](https://github.com/Netflix/fast_jsonapi)の2択になるのかなと思います。
エンジニアとしては、新しい技術をいれたくなるのはやまやまなのですが、以下の点を検討したあと、道入を決めました。

- 知見の確保先
- JSON:APIにフロント側が対応できるか
- JSON:API対応させるか、どこまで対応させるか
- 最悪の場合、AMSに乗り換えられるか

入れてみた雑感として、fast_jsonapi ですこし大変になってきそうなのが、JSON:API への対応だと思います。
自由に形を変えられる、jbuilderを考えると、天と地くらいあります。
結構特殊な、形をしているため、クライアントサイドとのすり合わせも必用です。

fast_jsonapiをいれる上で、Rails上で工夫した点等はいくつかあるのですが、其のへんのベストプラクティスがまとまる前に開発が終わってしまました。(TT)

ということで、今回はJSON:APIについて、現在僕が調べているところをざっくばらんに紹介していこうと思います。

# JSON:APIとは

jsonの構造の規約を定めたものです。
以下に公式のページがあります。
[jsonapi.org](https://jsonapi.org/)

JSON:APIがどのような立ち位置なのかといと、[こちら](https://nordicapis.com/how-does-jsonapi-compare-to-rest-and-graphql/)
で紹介されているのですが、GraphQLとREST の中間的な立ち位置になっています。
JSON:APIをリサーチした雑感でいうと、悪く書いている記事はほとんどありませんでした。

# JSON:APIのフォーマット

JSON:APIのフォーマットについて。[jsonapi.org](https://jsonapi.org/) とっぷにサンプルの構造がバンとはってありますが、すべてこのような感じのjsonで返します。
よくあるweb APIをつくるとなると、以下のようなフォーマットがおおくなるのではとおもいます。

```json
{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON:API paints my bikeshed!",
      "body": "The shortest article. Ever.",
      "created": "2015-05-22T14:56:29.000Z",
      "updated": "2015-05-22T14:56:28.000Z"
    },
    "relationships": {
      "author": {
        "data": {"id": "42", "type": "people"}
      }
    }
  }],
  "included": [
    {
      "type": "people",
      "id": "42",
      "attributes": {
        "name": "John",
        "age": 80,
        "gender": "male"
      }
    }
  ]
}
```

特徴的なのが、`type`, `relationships`  `included` といったところでしょうか。

`type` はリソースの名前が入ります。僕はModelの名前をいれていました。
`relationships`はリレーションが組んである、idとtypeが入ります。もし、関連データでidしかいらないとなった場合と、`included` からデータをもってくるときにつかいます、
`included` は、リレーションが組んである、データの詳細を返しているという感じですね。


この構造をみたときに、思うのが、

**パース面倒そうじゃない？？？**

です。

そうです。ここがちょっと苦労したところです。
[公式](https://jsonapi.org/implementations/) ではクライアント向けのライブラリーが何個も紹介されています。
この辺をつかえば、良い感じにうまくいきそうな気はしてました。
しかし、ここは僕の知見外になってしまうのですが、iOS側(Swift) のライブラリはうまくいかなかったパースが何個かあったみたいです。
なので、クライアント側のひとと相談が大切です。

また、POSTなどするときも、JSON:APIで定められている規約を使いたいです。
其の際の、Rails側でのパースはNetflix製の
[restful-jsonapi](https://github.com/Netflix/restful-jsonapi)
を使わせてもらいました。

こちらは特に苦労はなかったと思います。

# JSON:APIへの対応

JSON:APIをつかう上で、若干失敗したなと思ったのが、パラメータの既約を初期に設定しなかったことです。
ここは、僕の調査不足もあったのですが、前述したとおり、JSON:API はGraphQLとRESTの中間の立ち位置になります。
JSON:APIはGraphQLもどきのようなことができることも推奨しています。 [公式 Recommendations](https://jsonapi.org/recommendations/)

```
GET /comments?filter[post]=1,2&filter[author]=12 HTTP/1.1
```
このように パラメータでfilterしたり、includeできたりすることを推奨しています。
このような部分はなるだけ実装したいものです。クライアント側に伝えられず、途中から実装という形にしていきました。

また、この機能はfast_jsonapiに実装されているわけではなく、自分で良い感じに実装しないといけません。
そこも、なかなか大変だとおもいました。

# まとめ

今回は、fast_jsonapiというより、JSON:APIについて、所感をまとめました。
サービスが途中で終了してしまったため、運用上の知見をまとめあげるまではいけませんでした。
日本では、この辺の知見は落ちてないため、基本海外から引っ張ってくる形になるとおもいます。
海外だと、fast_jsonapiに関しても、JSON:APIに関しても悪い事は書かれていないように感じます。

JSON:APIの形式自体は、AMSも対応しているということもあり、RailsでREST APIをつくる上で、検討すべき点に入ってきます。
知見がすくないのも否めないので、実際に導入して、運用しているところの意見があれば、聞きたいです！

個人的には、このJSON:APIの規約どおりに、コードをまとめることができれば、運用は良い方向になるのではと思っています。

### twitterもフォローよろしくおねがいします。 ！
https://twitter.com/yoshixj


# 参考資料

Netflix medium
https://medium.com/netflix-techblog/fast-json-api-serialization-with-ruby-on-rails-7c06578ad17f

Netflix github
https://github.com/Netflix/restful-jsonapi

Error Serializer について
https://blog.codeship.com/the-json-api-spec/

AMS VS fast_jsonapi
https://medium.com/soundstripe-engineering/greener-pastures-migrating-a-production-api-from-activemodel-serializers-to-fast-json-api-9627be51c64

AMS VS fast_jsonapi
https://driggl.com/blog/a/from-activemodel-serializers-to-fast-jsonapi

JSON:API について喋っている動画
https://nordicapis.com/the-benefits-of-using-json-api/