Язык запросов для вашего API

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

Источник

GraphQL был разработан внутри Facebook в 2012 году, а позже был открыт в 2015 году. Идея возникла, когда Facebook решил перестроить свои мобильные нативные приложения. Они искали мощный API для извлечения данных, чтобы описать все требования Facebook к данным, но при этом достаточно простой для изучения и принятия разработчиками своих продуктов, и поэтому они перешли от идеи декларативной реализации API к языку запросов к полной стандартизированной спецификации GraphQL. ». Сегодня он обрабатывает миллиарды запросов API и широко применяется многими крупными технологическими гигантами, такими как Netflix, GitHub, в своих производственных приложениях.

REST и его недостатки

REST (REpresentational State Transfer) стал одним из широко распространенных и доминирующих архитектурных стилей программного обеспечения / API. Ключевой абстракцией, на которой основаны REST-совместимые системы, часто называемые системами RESTful, является ресурс. Любая информация, которая может быть идентифицирована и может быть названа, является ресурсом. например: документ, изображение, пользовательские данные и т. д. Поскольку REST ориентирован на ресурсы, он использует идентификатор ресурса (адрес URI) для идентификации этого конкретного ресурса, участвующего во взаимодействии (доступе, изменении) с системой. Ресурсы обрабатываются с помощью набора простых, четко определенных операций с использованием URI (уникальный идентификатор ресурса). Клиент и сервер обмениваются этими представлением ресурсов с помощью стандартного интерфейса и протокола (HTTP) и идентифицируются по URI.

например, HTTP GET для определенного URI извлекает ресурс (также иногда называемый объектом) и возвращает указанный сервером набор полей, HTTP PUT редактирует ресурс, HTTP DELETE удаляет объект. Рассмотрим здесь ресурс блог.

  • для доступа ко всем блогам: / blogs
  • в блог с идентификатором 27: / blogs / 27

различные операции с блогом будут такими

  • GET / blogs: сборник блогов
  • POST / blog: создать блог
  • PUT / blogs / 27: обновить блог, идентифицированный идентификатором 27
  • DELETE / blogs / 27: удалить блог с идентификатором 27

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

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

С REST API нам определенно приходится иметь дело с несколькими конечными точками и собирать необходимые данные. В нашем примере это может быть /users/id конечная точка для получения исходных данных пользователя. Затем /users/id/blogs, чтобы получить все блоги, которые понравились, и, наконец, /blogs/id/comments, чтобы получить все комментарии соответствующих блогов.

Теперь, поскольку данные, которые мы запрашивали, также сопровождаются другими ненужными данными, отфильтруйте данные соответствующим образом, прежде чем мы получим данные, которые нам нужны. Если это функционально часто используется, нам, вероятно, придется создать для него отдельную конечную точку. Опять же, у него будет свой собственный вызов, какой маршрут выбрать. Если бы в нашем специальном приложении было много таких сценариев ... было бы все более и более сложным и довольно трудоемким принятие решения и реализация конечных точек REST, и теперь REST больше не RESTful🥱.

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

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

query FetchUserBlogsAndCommentsQuery {
  user(id: "123"){
    id
    username
    email
    blogs{
      title
      description
      tags
      comments{
        author{
          username
        }
        text
      }
    }
  }
}

Затем сервер отвечает объектом JSON, в котором эти требования выполнены.

{
  "data":{
    "user":{
      "id": 123,
      "username": "John Doe",
      "email": "[email protected]",
      "blogs":[
        {
          "title": "Why GraphQL??",
          "description": "GraphQL was developed to cope with the need for more flexibility!",
          "tags": ["GraphQL", "REST", "API"],
          "comments":[
            {
              "author": {
                "username": "Jane Doe"
              }
              "text": "This blog clearly explains why GraphQL was needed, Helped a lot!!"
            }
          ]
        }
      ]
    }
  }
}

Как показано выше, используя GraphQL, клиент может указать именно те данные, которые ему нужны в запросе. Обратите внимание, что структура ответа сервера точно соответствует вложенной структуре, указанной в запросе. при этом логика приложения остается простой, а код в браузере получает именно те данные, которые ему нужны, с помощью одного запроса. С GraphQL мы можем улучшить REST😉.

Меньшие точные данные

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

Избыточная выборка ведет к загрузке большего количества данных

Чрезмерная выборка означает, что клиент загружает больше данных, чем фактически требуется приложению. Как описано в приведенном выше примере, если мы нажмем /users/id конечную точку, чтобы получить только идентификатор, имя пользователя и адрес электронной почты; Это приведет к возврату всех других данных, таких как DOB, адрес, местоположение и т. Д., Принадлежащих пользователю, которые на самом деле не нужны. чрезмерная выборка приводит к увеличению полезной нагрузки сети и, следовательно, к увеличению времени загрузки.

Недостаточная выборка для проблемы n + 1

Другая проблема заключается в недостаточной выборке, что означает, что конечная точка, с которой мы обращаемся для получения данных, не предоставляет достаточно того, что нам действительно нужно для нашего приложения. Подобные ситуации приводят к проблеме N + 1, когда клиент должен сделать еще один запрос к другой конечной точке, чтобы получить необходимые данные. Как упоминалось выше в сценарии со списком блогов, мы сначала должны получить сведения о пользователе с помощью этого запроса конечной точки блогов, и для каждого блога в возвращаемом списке сделать дополнительный запрос, чтобы получить все комментарии для соответствующих блогов с правильным именем пользователя (комментарий сведения об авторе), т.е. для каждого блога сделать запрос к /blogs/id/comments конечной точке.

Из-за этого множества циклов приема-передачи и избыточной / недостаточной выборки приложения, созданные на основе REST, неизбежно в конечном итоге создают специальные конечные точки. Они фактически связывают данные с определенным представлением. Для приложений с более широким обзором это может очень легко закончиться кошмаром обслуживания, связанным с массовым дублированием кода и потерянными конечными точками, что приведет к несогласованности.

Преимущества схемы и строго типовой системы

GraphQL использует строго строгую систему типов. Все типы и форма данных, представленных в API, определяются схемой с использованием языка определения схем GraphQL (SDL). Эта схема служит строгим контрактом для того, как выглядят операции, и для определения правильности запроса. при этом схема не только определяет ресурсы, доступные для извлечения, но также определяет принятые параметры при извлечении данных. API GraphQL организованы по типам и полям, а не по конечным точкам. Таким образом, клиенты могут просить только то, что можно вернуть.

Теперь, когда схема определена, команды фронтенд и бэкэнд могут использовать API без связи, поскольку они оба знают о форме данных, с которыми имеют дело.

Документация

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

Больше никаких версий API-интерфейсов

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

С GraphQL мы можем добавлять новые поля и типы, не нарушая / не влияя на существующие запросы / схему. Поля устаревания могут быть объявлены устаревшими и могут быть скрыты от доступа. Используя единую развивающуюся версию, GraphQL предоставляет API, чтобы наше приложение постоянно получало доступ к новым функциям, поощряя более чистую и удобную реализацию API.

Повышение производительности и быстрые итерации интерфейса

Обычная практика с REST API - структурировать конечные точки в соответствии с представлениями внешнего интерфейса. Это удобно, поскольку позволяет клиентам получать все данные, необходимые для определенного представления, просто обращаясь к соответствующей конечной точке. Однако у этого подхода есть и серьезный недостаток; он не допускает развития взглядов и быстрой итерации интерфейсов. с каждым изменением, которое мы вносим в наши представления, мы сталкиваемся с риском того, что теперь данных больше или меньше, чем раньше, и поэтому адаптация к развивающемуся пользовательскому интерфейсу становится довольно сложной. Бэкэнд должен адаптироваться, а также учитывать новые потребности в данных. Это снижает продуктивность разработки, а при избыточной / недостаточной выборке заметно снижает производительность.

GraphQL был разработан, чтобы удовлетворить потребность в большей гибкости и эффективности! Это решает многие подобные недостатки. Благодаря его гибкому характеру и системе типов клиенты могут точно указать, что им нужно, без необходимости вносить изменения в базовый API.

ОТДЫХ - ХОРОШО GraphQL - ЛУЧШЕ

Дело не в том, что REST полностью плох и скоро умрет, просто REST - это архитектурный стиль, а не формальный протокол. На самом деле ведутся споры о том, что такое REST, а что нет. В GraphQL мы представляем новый способ структурирования контракта клиент-сервер. Sever публикует систему типов для конкретного приложения, GraphQL предоставляет унифицированный язык для запроса данных в рамках заданных ограничений системы типов. Этот язык позволяет разработчикам выражать свои точные требования к данным в декларативной и иерархической форме. ОТДЫХ может жить долго.

GraphQL был разработан с учетом недостатков и проблем при разработке, масштабировании и поддержке REST API, с лучшей производительностью, точной полезной нагрузкой, адаптируемостью, более сильной системой типов и декларативным подходом к выборке данных GraphQL - лучший REST . С момента своего публичного выпуска в 2015 году GraphQL быстро вырос до такой степени, что его можно адаптировать практически к любой инфраструктуре и архитектуре. Сообщество, экосистема связанного программного обеспечения, а также адаптивность компании росли с невероятной скоростью. Такие компании, как GitHub, Netflix, Airbnb, Coursera, New York Times, Shopify и многие из них, как известно, уже внедрили GraphQL в свои технические стеки.

📚 Дополнительная литература и ресурсы

👉 Этот пост изначально был опубликован на моем личном блоге

Связаться

Привет, есть какие-либо предложения, вопросы или проблемы. Не стесняйтесь, напишите мне. Вы также можете найти меня в Twitter, GitHub и LinkedIn. Помогите мне сделать это лучше, напишите мне сообщение, и я скоро перезвоню вам Спасибо! 🎉