masalibの日記

システム開発、運用と猫の写真ブログです

GraphQL:概要

次回の会社の勉強会のために調べているGraphQLについてコツコツ書いていきます

本は今の所は英語しかないみたい

Learning GraphQL: Declarative Data Fetching for Modern Web Apps

Learning GraphQL: Declarative Data Fetching for Modern Web Apps

雑誌だとWEB + DB PRESSであったくらい

WEB+DB PRESS Vol.104

WEB+DB PRESS Vol.104

  • 作者: 末田卓巳,林田千瑛,陶山嶺,八谷賢,辰己佳祐,竹澤俊季,服部智,藤岡裕吾,牧大輔,西郡卓矢,松木雅幸,穴井宏幸,新日出海,桑原仁雄,小田知央,ひげぽん,池田拓司,はまちや2,竹原,大場光一郎,大場寧子,松館大輝,日高尚美,Vu Xuan Dung,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/04/24
  • メディア: 単行本
  • この商品を含むブログを見る

GraphQLとは

GraphQLは、RESTの代わりに、より効率的で、強力で柔軟な新しいクエリ言語です。Facebookによって開発され、オープンソース化され、現在世界中の企業や個人の大規模なコミュニティによって維持管理されています。 データベース技術と混同されますがそれは間違いです。GraphQLはデータベースではなくAPIのクエリ言語。

今年も注目された技術の1つですが、来年以降はもっと注目されると思います。
私の個人的な意見ですが、いずれはSQLと同じくらい有名になり、そして必須になる

FaceBookがGraphQL開発した理由

最初の理由は、携帯電話の使用量の増加、低消費電力のデバイス、低速なネットワークだった。 GraphQLは、ネットワーク経由で転送する必要があるデータの量やリクエスト数を最小限に抑えてアプリケーションパフォーマンスを改善した エンドポイントを減らすことでセキュリティーな点でもメリットがある。

RESTについて

RESTful API(REST API)とは、Webシステムを外部から利用するためのプログラムの呼び出し規約(API)の種類の一つで、RESTと呼ばれる設計原則に従って策定されたもの。RESTそのものは適用範囲の広い抽象的なモデルだが、一般的にはRESTの考え方をWeb APIに適用したものをRESTful APIと呼んでいる。

RESTful APIでは、URL/URIですべてのリソースを一意に識別し、セッション管理や状態管理などを行わない(ステートレス)。同じURLに対する呼び出しには常に同じ結果が返されることが期待される。

また、リソースの操作はHTTPメソッドによって指定(取得ならGETメソッド、書き込みならPOSTメソッド)され、結果はXMLやHTML、JSONなどで返される。また、処理結果はHTTPステータスコードで通知するという原則が含まれることもある。 IT用語辞典 e-Wordsより引用

RESTの問題点

エンドポイントを変更しにくい設計のため、サーバー側は全データを渡してクライアント側で切り捨てる必要があった。

例えば https://api.spacexdata.com/v3/launches/ という実際にあるAPIがあるのですがこちらを実行すると

curl --location --request GET "https://api.spacexdata.com/v3/launches/67"```

実行結果

{
    "flight_number": 67,
    "mission_name": "Merah Putih",
    "mission_id": [],
    "launch_year": "2018",
    "launch_date_unix": 1533619080,
    "launch_date_utc": "2018-08-07T05:18:00.000Z",
    "launch_date_local": "2018-08-07T01:18:00-04:00",
    "is_tentative": false,
    "tentative_max_precision": "hour",
    "tbd": false,
    "rocket": {
        "rocket_id": "falcon9",
        "rocket_name": "Falcon 9",
        "rocket_type": "FT",
        "first_stage": {
            "cores": [
                {
                    "core_serial": "B1046",
                    "flight": 2,
                    "block": 5,
                    "gridfins": true,
                    "legs": true,
                    "reused": true,
                    "land_success": true,
                    "landing_intent": true,
                    "landing_type": "ASDS",
                    "landing_vehicle": "OCISLY"
                }
            ]
        },
        "second_stage": {
            "block": 5,
            "payloads": [
                {
                    "payload_id": "Telkom-4",
                    "norad_id": [
                        43587
                    ],
                    "reused": false,
                    "customers": [
                        "Telkom"
                    ],
                    "nationality": "Indonesia",
                    "manufacturer": "SSL",
                    "payload_type": "Satellite",
                    "payload_mass_kg": 5800,
                    "payload_mass_lbs": 12786.81,
                    "orbit": "GTO",
                    "orbit_params": {
                        "reference_system": "geocentric",
                        "regime": "geostationary",
                        "longitude": -108,
                        "semi_major_axis_km": 42164.903,
                        "eccentricity": 0.0001369,
                        "periapsis_km": 35780.995,
                        "apoapsis_km": 35792.54,
                        "inclination_deg": 0.0164,
                        "period_min": 1436.105,
                        "lifespan_years": 15,
                        "epoch": "2018-12-21T10:48:03.000Z",
                        "mean_motion": 1.00271174,
                        "raan": 0.6016,
                        "arg_of_pericenter": 293.1094,
                        "mean_anomaly": 66.2895
                    }
                }
            ]
        },
        "fairings": {
            "reused": false,
            "recovery_attempt": false,
            "recovered": false,
            "ship": null
        }
    },
    "ships": [
        "HAWK",
        "OCISLY"
    ],
    "telemetry": {
        "flight_club": null
    },
    "launch_site": {
        "site_id": "ccafs_slc_40",
        "site_name": "CCAFS SLC 40",
        "site_name_long": "Cape Canaveral Air Force Station Space Launch Complex 40"
    },
    "launch_success": true,
    "links": {
        "mission_patch": "https://images2.imgbox.com/a8/f5/ZgdsrbqW_o.png",
        "mission_patch_small": "https://images2.imgbox.com/a7/ec/sbwePzVD_o.png",
        "reddit_campaign": "https://www.reddit.com/r/spacex/comments/91gwfg/merah_putih_telkom4_launch_campaign_thread/",
        "reddit_launch": "https://www.reddit.com/r/spacex/comments/9539nr/rspacex_merah_putih_telkom4_official_launch/",
        "reddit_recovery": null,
        "reddit_media": "https://www.reddit.com/r/spacex/comments/94zr0b/rspacex_merah_putih_media_thread_videos_images/",
        "presskit": "https://www.spacex.com/sites/spacex/files/merahputihpresskit.pdf",
        "article_link": "https://spaceflightnow.com/2018/08/07/indonesian-communications-satellite-deployed-in-orbit-by-spacex/",
        "wikipedia": "https://en.wikipedia.org/wiki/Telkom_Indonesia",
        "video_link": "https://www.youtube.com/watch?v=FjfQNBYv2IY",
        "flickr_images": [
            "https://farm2.staticflickr.com/1798/43862495212_8fe1688c4b_o.jpg",
            "https://farm1.staticflickr.com/935/43006330655_f1623a3fa1_o.jpg",
            "https://farm1.staticflickr.com/938/28974313177_d16381ff5f_o.jpg",
            "https://farm2.staticflickr.com/1780/43006334045_fb7b4a8714_o.jpg",
            "https://farm1.staticflickr.com/929/28974335747_ffd87ff274_o.jpg",
            "https://farm1.staticflickr.com/930/30041972208_f735b9690b_o.jpg"
        ]
    },
    "details": "SpaceX's fifteenth flight of 2018 launched the Merah Putih (also known as Telkom-4) geostationary communications satellite for Telkom Indonesia. It marked the first reuse of any Block 5 first stage; the booster B1046 had previously launched Bangabandhu-1. The stage was recovered and is expected to become the first Falcon 9 booster to fly three missions.",
    "upcoming": false,
    "static_fire_date_utc": "2018-08-02T15:53:00.000Z",
    "static_fire_date_unix": 1533225180
}

このようにRESTAPIの性質的にすべて取ってくる事が非常にネットワーク的にもったいないのです。

また紐づけされたデータがある場合は再度RESTAPIを叩く必要があるためトラフィックが増える傾向だった。

RESTとgraphqlの違いについて

REST APIを使用すると、通常は複数のエンドポイントに アクセスしてデータを収集します。 例えばで/users/は、初期ユーザーデータを取得するためのエンドポイントです。 第2に、/users//postsユーザーのすべての投稿を返すエンドポイントが存在する可能性があります。 3番目のエンドポイントは、 ユーザーあたりのフォロワーのリストを 返すエンドポイントになり/users//followersます。

f:id:masalib:20181205211346p:plain

GraphQLでは、具体的なデータ要件を含む単一のクエリをGraphQLサーバに送信するだけです。 サーバーは、これらの要件が満たされているJSONオブジェクトで応答します。 サーバーサイドでは複数の問い合わせが発生しますが、クライアント側には1つしかない所が利点です

f:id:masalib:20181205211524p:plain

https://www.howtographql.com/basics/1-graphql-is-the-better-rest/ より引用

RESTの資産について

今まで作ったRESTAPIはオワコンというわけではないです。GraphQLから呼び出す事が可能なのでそのまま使えます。今後、作成するならGraphQLに移行した方が無難です。

クライアント側を覚えるならgithubが最適!!

色々と記載しましたが私みたいなアホな人間は実際にやらないと覚えられない。 実際に「GraphiQL」やって覚えたほうが早い。

developer.github.com