[Из песочницы] Сравнение REST и GraphQL

Комментарии (58)

  • 8 августа 2017 в 13:28 (комментарий был изменён)

    +2

    Т.е. вместо того чтобы отталкиваться от предметной области задачи, требований к данным со стороны клиента.
    люди постоянно придумывают себе границы в виде каких-то REST API или GraphQL, которые вместо того чтобы помогать, на самом деле только ограничивают гибкость.
    Что мешает думать о HTTP API как об интерфейсе команда-результат, где не обязательно наличие каких-то осмысленных ресурсов, CRUD и т.п. операций.
    Зачем это всё?
    • 8 августа 2017 в 13:39 (комментарий был изменён)

      +1

      как об интерфейсе команда-результат

      Ну вот GraphQL как раз ближе гораздо к этому чем REST API. Один ендплоинт куда отправляешь запросы на выборку только необходимых данных или на обновление данных. То есть оперируешь сущностями подобно таблицами в SQL (строя связи в запросах), а не ендпоинтами которые повешаны поверх сущностей в случае REST API.


      PS вообще подобный OData стандарт существовал до GraphQL.

      • 8 августа 2017 в 13:50

        +1

        Все это хорошо, но не жизнеспособно. Т.к. любой API между сервером и клиентом является публичным, т.о.
        им может воспользоваться злоумышленник.

        Под схемой команда-результат я понимал самый простой интерфейс, когда команда — некий идентификатор команды + список некоторых параметров для этой команды.
        В данном случае это позволяет полностью видеть и контроллировать затраты на выполнение каждой команды.
        В случае гибкого GraphQL разработчик сервера не в состоянии понять какие данные должны быть доступны клиенту, и какова вообще сложность получения этих данных.

        По аналогии с SQL, если вы откроете доступ к БД, то злоумышленник может сделать SQL запрос с кучей join которые тупо повесят ваш сервер БД (вам же это не хочется, правда ?). Разве сам по себе GraphQL может защитить от такой участи? Я думаю нет, а раз нет — то зачем это всё нужно?

        • 8 августа 2017 в 14:12

          0

          а БД как решает проблему кучи джойнов? И почему GraphQL ее должен решать, если это не его задача?

          • 8 августа 2017 в 14:17

            +1

            А вы выставляете БД в мир и говорите, приди сюда плохой человек, я дам своему хостеру 100500 денег на твой запрос?

            GraphQL — решение для публичного API, поэтому он должен решать этот вопрос. Иначе грош цена дырявому интерфейсу.

            • 8 августа 2017 в 14:24 (комментарий был изменён)

              +1

              А вы выставляете БД в мир и говорите, приди сюда плохой человек, я дам своему хостеру 100500 денег на твой запрос?

              нет, конечно. Я, как разработчик api, и в graphql не дам выполнять все что душе угодно.


              GraphQL — решение для публичного API, поэтому он должен решать этот вопрос. Иначе грош цена дырявому интерфейсу.

              graphql — это спецификация клиентского апи, и не описывает серверную реализацию от слова «совсем». Так же как спецификация языка sql не описывает реализацию базы данных и защиту от множественных джойнов.

              • 8 августа 2017 в 14:35 (комментарий был изменён)

                0

                Ваш сервер либо соотвествует спецификации и тогда это GraphQL сервер, либо нет.
                > нет, конечно. Я, как разработчик api, и в graphql не дам выполнять все что душе угодно.
                ну т.е. мы пошли в софизмы и теперь говорим что где-то мы поддерживаем GraphQL, а где-то нет.
                Значит вы делаете не GraphQL сервер.

                Мой вопрос состоит в том, как из самого запроса понять его сложность? Понять насколько он сложен для машины, и вовремя его отбросить чтобы заняться чем-то другим. Есть решения этого вопроса?
                Когда вы делаете SQL-запрос, сервер обязан отдать вам результат и он его ищет.
                Когда вы делаете GraphQL запрос, вы вольны делать что угодно. Но опять же в случае какого либо RPC (как выше назвали этот подход), это позволяет контроллировать все аспекты взаимодействия. И т.о. даже если клиент генерирует вредоносные для сервера запросы, сервер может их просто игнорировать используя простые правила фильтрации.
                В случае GraphQL, эта спецификация дает бесконечное множество путей получения данных.
                И мой вопрос состоит в том, каким образом это множество можно ограничить до разумных пределов, чтобы контроллировать производительность сервера и «хорошие намерения» клиента.
                Вопрос понятен?

                • 8 августа 2017 в 14:40

                  0

                  И мой вопрос состоит в том, каким образом это множество можно ограничить до разумных пределов, чтобы контроллировать производительность сервера и «хорошие намерения» клиента.

                  даже если клиент генерирует вредоносные для сервера запросы, он может их просто игнорировать используя простые правила фильтрации

                  все аналогично. Спецификация описывает язык запросов, а не бесконечную вложенность или сотни методов получения.

                  • 8 августа 2017 в 14:50

                    0

                    Спецификация — это спецификация. Таким же макаром можно поддреживать ограниченный SQL и все тоже самое будет. Меня интересует вопрос более общего плана.
                    В случае RPC мы каждой команде можем сопоставить однозначную стоимость её выполения, причем сделать это заранее.
                    Когда за единицу времени клиент генерирует слишком большую стоимость, мы можем его игнорировать.
                    Теперь возьмем «универсальный интерфейс», которые позволяет нам генерить кучу запросов, и получать данные даже такие, которые разработчик интерфейса и не думал что они будут запрошены.
                    Мой вопрос состоит в том, как из самого запроса получить стоимость его выполнения?
                    В случае RPC всё просто, в случае GraphQL всё неоднозначно. Пока не выполнилнишь, не поймешь. Т.о. этот универсальный путь открывает такие очень хорошие возможности по «нагружанию» вашего сервера. А зачем оно вам вообще это надо?
                    • 8 августа 2017 в 15:08

                      0

                      В случае RPC всё просто, в случае GraphQL всё неоднозначно.

                      на самом деле ни в первом ни во втором случае не все так, как вы говорите. Необязательно стоимость запроса известна заранее, если RPC поддерживает вложенность ответа (а RPC это не оговаривает), и необязательно стоимость заранее неизвестна при работе с GraphQL, если сервер позволяет запрашивать сущности 1–2 вложенностей максимум, без рекурсии (реализацию GraphQL тоже не оговаривает).
                      Это все детали реализаций — вложенность, рекурсия, rate limiting, security, authorization/authentification итд. Сама спека только о языке запросов.

        • 8 августа 2017 в 15:44

          0

          По аналогии с SQL, если вы откроете доступ к БД, то злоумышленник может сделать SQL запрос с кучей join которые тупо повесят ваш сервер БД (вам же это не хочется, правда ?).

          именно поэтому удобно использовать хранимые процедуры, к которым доступ открыт, а к таблицам и прямыми запросами к ним закрыт. в процедуре об этом злоумышленнике подумали заранее.

    • 8 августа 2017 в 14:10

      0

      То, о чем вы пишете есть RPC и существует очень давно. Разве что раньше никак не называли этот подход, а начали называть только с приходом REST и иже с ними.

      Когда вы занимаетесь разработкой как backend, так и frontend, то можете «точить» одно под другое. Но, если у вы пишете только backend, а frontend будут писать совсем другие люди и коммуникации между вами не будет, то вы не можете заранее знать что frontend будет «хотеть».

      Поэтому существует такая штука как REST. Этот подход зачастую избыточен, но независим от сценариев использования.
      А GraphQL по сути попытка убрать из REST избыточность.

      • 8 августа 2017 в 14:23 (комментарий был изменён)

        0

        Невозможно сделать универсальный интерфейс, т.о. взаимодействие разработчиков всегда необходимо.
        Таким макаром можно SQL в свет выложить :) пусть пользует. А что, очень универсально.
        • 8 августа 2017 в 14:28

          0

          Взаимодействие не всегда возможно.

          Пример: Публичное API.

          Согласитесь, что Facebook, например, скорее всего не будет затачивать свое API для вашего мобильного приложения. Т.е. взаимодействия между разработчиками API и разработчиками frontend’а нет и в данном случае быть не может.

          • 8 августа 2017 в 14:42

            0

            Не соглашусь. Разработчики API facebook понимают какие данные нужны людям, и предоставляют эти данные в удобном для людей виде. Т.о. взаимодействие есть, но косвенное.
            Не бывает сферического API в вакуме. В случае GraphQL это именно этот конь и есть.
            • 8 августа 2017 в 14:48

              +1

              Они не могут знать что надо всем. Потому что кому-то что-то надо, а кому-то нет. Кто-то может сделать дополнительный запрос, а кому-то это «дорого».

              Когда вы сами пишете API, вы можете все «запихать» в 1 запрос. Когда вы используете чужое API, возможно 2 и более запросов. Хуже, когда все выливается в N+1 запросов. А все потому что разработчик API не может знать что вам надо и делать API для вас. У него таких как вы еще 100500 и каждому что-то надо. И в случае с REST такое бывает часто.

              И да, не бывает сферического API в вакуме. О чем я и пишу.

              • 8 августа 2017 в 14:59 (комментарий был изменён)

                0

                Я с вами согласен по части «не могут знать», поэтому они делают как лучше для них.
                Конечно, вы можете сделать 2 запроса и получить 2 результата на что уйдет 2х времени.
                Если вы хозяин API, и видите боль, ну ничего не мешает вам организовать простой интерфейс где возможно сразу выполнить много команд. Проблемы возникнут когда одна команда зависит от другой. Конечно, GraphQL, возможно, решает эту проблему, но опять же я вижу другую проблему — это слишком общий путь получания данных, и эта очень сильная беда как с точки зрения реализации, так и с точки зрения ограничения нагрузки.

                Я как бы не против всяких GraphQL и SQL. Я против того, чтобы это было выложено в паблик без должной работы по ограничению стоимости запросов. И т.о. сам запрос должен содержать в себе информацию о том, какова его сложность выполнения. Есть работы по анализу этого?

            • 8 августа 2017 в 15:13 (комментарий был изменён)

              0

              Разработчики API Facebook и разработчики GraphQL это одни и теже люди. Более того GraphQL это основной API в Facebook:


              https://developers.facebook.com/docs/graph-api

              • 8 августа 2017 в 16:00 (комментарий был изменён)

                0

                У них когда-то был FQL. Но его закрыли.
                Вот как сейчас у Facebook спросить список галерей с количеством фотографий в них? У самой галереи нет счатчика? Запросить сразу все фотографии нельзя. Там еще пейжинг есть.

                С их текущим REST это сделать очень больно.
                Как с помощью GraphQL это сделать? Т.е. не просто ограничить набор полей в выводе, а добавить агрегирующие функции?

                С помощью FQL это было сделать можно. Но, нет больше FQL.

  • 8 августа 2017 в 13:53 (комментарий был изменён)

    +1

    когда команда — некий идентификатор команды + список некоторых параметров для этой команды.

    Так делаем сколько нужно ендпоинтов с соответствующей логикой и все, это REST API и есть. Называет ендпоинты командами или чем угодно, а не сущностями и все. Так делают уже десятки лет.


    В случае гибкого GraphQL дело как раз в унификации, как раз в этом цель и есть чтобы выставить ДБ наружу образно говоря, но конечно не напрямую как некоторые могут подумать.

    • 8 августа 2017 в 14:11 (комментарий был изменён)

      0

      Только это уже будет не REST, а RPC. Хороший (и удобный) REST API написать достаточно тяжело. Очень легко скатиться и начать нарушать его принципы. Иногда оправдываясь такими словами как первоманс.
      • 8 августа 2017 в 14:12

        0

        Если смотреть на детали, то да, но REST просто получается более частная форма вызова конкретных ендпоинтов.

        • 8 августа 2017 в 14:14

          0

          Все верно.
          RPC — делаю что хочу и как хочу. Уже REST есть какие-то правила.
          А вот воблюдать их или нет — дело выбора каждого.
  • 8 августа 2017 в 14:11

    0

    у GraphQL есть небольшие отличия, которые существенно меняют процесс построения и использования API разработчиками

    не скажу ничего нового, но это небольшое отличие заключается в создании ада на зем бэк-енде.

    и ведь что характерно, очень много новых постов о GQL почему-то вместо акцента на реальных преимуществах и границах применимости, просто позиционируют его как убийцу REST/SOAP/RPC/чегоугодно… аргументируя это «смотрите как можно через один эндпоинт всё сделать!». мыслевирус в чистом виде.

    а то, что статья вроде как бы просто сравнивает подходы, мало меняет её основной посыл.

    • 8 августа 2017 в 17:12

      0

      Статья, на мой взгляд, лишь пытается выделить сущности, выполняющие схожие функции, в двух парадигмах построения API — несмотря на разницу в терминах, деталях внутренней реализации и алгоритмах работы.
  • 8 августа 2017 в 14:32 (комментарий был изменён)

    0

    Разница в том, что rest описывает правила работы над данными.
    А GraphQL описывает ещё и логику, точно также, как и любая другая концепция datastorage.

    Первое, это правило по которому нельзя сувать пальцы в розетку.
    А второе, что нельзя сувать пальцы в розетку — сидя, стоя, стоя на одной ноге, в прыжке, в припляску и т.д.

  • 8 августа 2017 в 14:52

    0

    Ноль информации. Судя по статье, вся революционность в том, что стартаперы придумали слать сериализованый объект запроса к REST с получением сериализованного объекта ответа и назвали это убийцей REST.

    Может кто-то более понятно объяснить суть технологии? Пока вижу кучу шума и небольшую надстройку на старой рабочей лошадкой.

    • 8 августа 2017 в 15:11

      0

      Вы однажды организуете данные и потом фронтенд-разработчик делает что хочет. Без необходимости что-то дорабатывать. К примеру, отдает ресурс данные об авторе. В виде его ID. Это не удобно — требуется делать доп. запросы. Фронтендщик это замечает и обращается к бэкендщику. Это в случае с Rest. В случае с Graphql этого, теоретически, не потребуется. Плюс — Graphql позволяет уточнять, какие из данных нужны. Чтобы лишнего не прилетало. Это в теории. На практике это, конечно, было бы удобно. Но есть и куча минусов.
      • 8 августа 2017 в 15:38

        0

        А чем именно это отличается от доступа через апи к нормальной БД со всеми необходимыми ключами, связями и т.д.? Вот прямо сейчас работаю над проектом, где легко можно пойти по такому примерно адресу:

        http://192.168.1.175:1337/api/accounts/33/companies

        Получим в виде JSON все компании из таблицы companies связанные по внешнему ключу c записью в таблице accounts с id 33.

        Причём все эти вещи не прописываются руками, апи умеет читать связи в базе данных и единственное что требуется при обновлении её структуры — запустить скрипт конфигурации.

        • 8 августа 2017 в 16:44

          0

          Я сам к Graphql отношусь скептически. Не потому, что не люблю все новое. Идея, как мне кажется, просто крутейшая. Но пока технология не очень устоялась. Мое мнение личное, никому не навязываю.

          А касаемо чем отличается. Так ничем не отличается, наверное. За исключением нюансов. Но Graphql — это, по крайней мере, попытка запихнуть хорошую идею в технологию. А не на коленке что-то выдумать. А раз так — можно попробовать дать ей пару лет и посмотреть. Может что и получится хорошее.

  • 8 августа 2017 в 15:07 (комментарий был изменён)

    –1

    Я думаю, некоторые из различий говорят в пользу GraphQL. В частности, мне кажется, действительно здорово иметь возможность реализовать свой API как набор небольших функций-распознавателей, а затем отправлять сложные запросы, которые предсказуемым способом извлекают множество ресурсов за один раз.

    А потом кто-то откапывает ваш API и такой:

    {
      authors {
        firstName
        posts {
          title
          author {
            firstName
            posts{
              title
              author {
                firstName
                posts {
                  title
                  [n author]
                    [n post]
                }
              }
            }
          }
        }
      }
    }

    А в ответ ему прилетает целая торба данных. Которая валит сервер. В чистом виде преимущества Graphql перед Rest несомненны. Практика расставляет все точки.
    • 8 августа 2017 в 15:15

      0

      А в ответ ему прилетает

      {«error»: «Three levels are allowed maximum.»}

      • 8 августа 2017 в 16:41

        –1

        Ну, а точно прилетает? Есть какие-то фреймы?
        • 8 августа 2017 в 16:44

          –1

          Ну, а точно прилетает?

          у вас разве не гипотетический вопрос? как я могу точно ответить? это деталь реализации, к graphql не имеющая отношения.

          • 8 августа 2017 в 16:49

            –1

            А, ну тогда не принимается. Принял бы ответ «используем такой-то фрейм, полет нормальный, ничо там не прилетает». А теоретическую возможность ограничить level я даже за решение не приму. Это костыль.
        • 8 августа 2017 в 16:45

          –1

          точно так же как и в ресте есть параметр limit и его максимум. Если реализовали — лимит есть, если нет — АПИ дырявое, что рест, что графкл
          • 8 августа 2017 в 16:48

            –1

            Ограничивать вложенность — это костыль. Это костылище костыльный.
            • 8 августа 2017 в 16:50

              –1

              Почему?
              • 8 августа 2017 в 16:50

                0

                Потому, что это ограничивает не только вредоносные. Но и пользоносные запросы. А если где-то надо будет level 5+? Ну вот надо. А мы бахнули всех под одну гребенку.
                • 8 августа 2017 в 16:56 (комментарий был изменён)

                  0

                  еще раз: реализация ваша. Как хотите так и делайте. На один запрос 5 уровней, на другой 1, на третий — интеллектуально. Это не костыль — это так надо делать.


                  get-запрос на /products (в парадигме rest) должен отдать миллион продуктов или ограниченное на сервере количество? Решать разработчику серверной стороны.

                  • 8 августа 2017 в 16:59

                    0

                    Вот-вот. Мне сначала тоже «да давай заюзаем Graphql, не надо будет роутинги, ваще ничо не надо будет». А я взял и послушал. Теперь расхлебываю.
              • 8 августа 2017 в 16:55

                0

                Не помню, где-то общался со специалистом, который от меня не знал, куда деться. Он тоже о Graphql рассказывал. И он предлагал знаете, как. Вот мы начали выполнять Graphql-запрос. И заранее определяемся, скажем — мы готовы выполнять запросы в среднем за 0,1с и затрачивать на это столько-то ресурсов. Начинаем выполнять запрос — начинаем считать. Если ресурсов или времени тратится больше, чем надо — отрубаем запрос.

                Это примерно из той же оперы. Низкая кучность стрельбы компенсируется увеличением диаметра снаряда.

      • 8 августа 2017 в 16:48

        0

        И кстати, для приведенного мной варианта трех уровней было бы вполне достаточно, чтобы серверу ощутимо дать под дых. Такими запросами ддосить кого-то — одно удовольствие.

        И потом — если три уровня максимальны, то вообще-то их может и не хватить. Что тогда? Придется делать какие-то запросы разрешенными, какие-то запретными. Еще раз повторяю — Graphql очень крут. Флаг в руки. Но как только возникает что-то подобное, сразу становится понятно, что принцесса-то… небритый мужик.

        • 8 августа 2017 в 16:51

          –1

          И кстати, для приведенного мной варианта трех уровней было бы вполне достаточно, чтобы серверу ощутимо дать под дых.

          вы, как разработчик вашего api, знаете сколько уровней достаточно. Столько и сделайте. Сотый раз: graphql не описывает серверную реализацию.


          Но как только возникает что-то подобное, сразу становится понятно, что принцесса-то… небритый мужик.

          вы просто не понимаете, что эта спецификация о языке запросов

          • 8 августа 2017 в 16:58

            0

            Я ни слова претензии в адрес теоретической составляющей и не высказал. Внимательнее надо читать — я описываю нюансы реализации и говорю, что не все так безоблачно. А вот почему от вас бурная реакция — вопрос. Я ничего не наврал, никого не оскорбил.
            • 8 августа 2017 в 17:04

              –1

              я внимательно читаю:


              Еще раз повторяю — Graphql очень крут. Флаг в руки. Но как только возникает что-то подобное, сразу становится понятно, что принцесса-то… небритый мужик.

              если принцесса — разработчик, то вы правы. Ведь к GraphQL эти претензии не относятся. Но в комментах к каждой статье про GraphQL одно и то же —, а именно непонимание что собственно это такое.


              А вот почему от вас бурная реакция — вопрос

              если будете внимательнее читать, то не будете переносить свое настроение на оценку моей реакции.

          • 8 августа 2017 в 17:06

            0

            Тогда я прямо сейчас вам готов родить отличнейшую концепцию. Там вообще ничего не потребуется.

            Короче. Надо постировать на сервак прямо SQL-запросы. А уже на сервере разгребать, что из этого вредоносное, а что нет. Но это уже ваша проблема. Как технология? Я считаю, крутяк!)))

    • 8 августа 2017 в 16:56

      +1

      А в случае REST API можно забыть добавить аутентификацию и авторизацию для конечной точки, и злоумышленник получит данные, к которым он по идее не должен иметь доступа.

      Или другой сценарий: конечная точка, возвращающая список данных, разбитых на страницы, не проверяет входные параметры, присылаемые клиентом. В результате можно запросить весь список целиком или просто очень много элементов на одной странице, и сервер свалится из-за огромного объема запрошенных данных.

      GraphQL — всего лишь концепция построения интерфейса доступа, которая ослабляет связанность клиента и сервера. На мой взгляд, проблема, которую вы описываете, вообще не имеет отношения к тому, на чем у вас реализован API. Это скорее вопросы информационной безопасности.

      • 8 августа 2017 в 17:03

        0

        То есть, защита от дурака — проблема дурака?
        • 8 августа 2017 в 17:09

          0

          написано ровно наоборот: если парадигмально по GET /products мы получаем список продуктов, то не надо забывать о здравом смысле (читай, лимите).

          • 8 августа 2017 в 17:16

            0

            Это никак не связанные вещи. То, что при реализации Graphql принято делать костыли и это норма я уже понял. Теперь я пытаюсь выведать нюансы.

            Сравнивать уровень вложенности Graphql запроса и количество отдаваемых пагинатором сущностей — это ерунда полная. Это совершенно разные лимиты и влияют они на работу сервера по-разному.

            Для меня абсолютно не аргумент, что тут у нас теория, а тут у нас практика. Теория и практика обслуживают друг друга и разделять их совсем было бы глупо. Если у авторов этого чудесного стандарта не нашлось идей, как этот Graphql столь же красиво реализовать, это говорит о многом.

            • 8 августа 2017 в 17:21

              0

              у авторов этого чудесного стандарта не нашлось идей, как этот Graphql столь же красиво реализовать, это говорит о многом.

              и еще раз: спецификация рассказывает о том как общаются клиент и сервер, а не как сервер обрабатывает запросы.


              Вот ниже давали ссылки на json-api. Вы спеку читали? там есть вообще что-то про серверную реализацию? Почему в случае с graphql должна быть другая ситуация?

  • 8 августа 2017 в 15:18

    +2

    подобных статей сотни… да все уже поняли, что есть «специфи

    © Habrahabr.ru