Език за заявки за вашия 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 : актуализирайте блога, идентифициран с id 27
  • DELETE /blogs/27 : изтрийте блог, идентифициран с id 27

Базираността на ресурсите обаче е чудесен подход и работи добре в много ситуации, но идва с недостатъци поради самата си природа и така става трудно, доста по-сложно за справяне, когато системите растат. Нека разгледаме ситуация, в която имаме блог приложение, както е дефинирано по-горе, с функции, при които потребителите могат да добавят блогове, да коментират различни блогове и така нататък...

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

С REST API определено трябва да се справим с множество крайни точки и да съберем необходимите данни. В нашия пример това може да бъде /users/id крайна точка за извличане на първоначалните потребителски данни. След това /users/id/blogs, за да извлечете всички блогове, които са били харесани, и накрая /blogs/id/comments, за да получите всички коментари на съответните блогове.

Сега, тъй като данните, които поискахме, също са придружени от други ненужни данни, тогава филтрирайте данните по съответния начин, преди да получим данните, които желаехме. Ако това функционално се използва често, тогава вероятно трябва да създадем отделна крайна точка за него. Отново ще има собствено предизвикателство какъв маршрут да се избере. Ако нашето специално приложение имаше много такива сценарии...щеше да става все по-сложно и доста трудоемко🥴 вземането на решение и внедряването на REST-крайни точки и сега REST не става повече RESTful🥱.

Всеки път, когато искате да създадете нов екран за вашето приложение, трябва да започнете да пишете нов API на задната част, който да обслужва нуждите на този екран. По-голямата част от него е шаблонен и нищо от него не може да се използва многократно и в крайна сметка вие оплитате плътно вашия бекенд и вашето предно приложение, когато правите това.

В GraphQL, от друга страна, просто бихме формирали една заявка, описваща нашите конкретни изисквания за данни, и я изпратихме до API на GraphQL с 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 е този с над/недостатъчно извличане на данни, което също води до филтриране на ненужни данни. Това се случва главно, защото единственият начин клиентът да поиска данни е да достигне до множество крайни точки, които връщат фиксирана форма на данни. Много е трудно да се проектира API, който приема или предоставя точно данните, изисквани от клиента. GraphQL заявките винаги връщат предвидими резултати. Приложенията, използващи GraphQL, са бързи и по-стабилни, защото контролират данните, които получават.

Прекаленото извличане води до изтегляне на повече данни

Свръхизвличането означава, че клиентът изтегля повече данни, отколкото действително се изисква в приложението. Както е описано в горния пример, ако ударим /users/id крайна точка, за да получим само идентификатора, потребителското име и имейла; Това би довело до връщане на всички други данни като DOB, адрес, местоположение и т.н., принадлежащи на потребителя, които всъщност не са необходими. прекомерното извличане води до по-голям мрежов полезен товар и следователно повече времена за зареждане.

Проблем с недостатъчно извличане за n+1

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

Поради тези множество двупосочни обиколки и над/под извличане, приложенията, изградени в REST, неизбежно в крайна сметка изграждат ad hoc крайни точки. Те всъщност свързват данните към определен изглед. За приложения с по-широк изглед това може много лесно да се превърне в кошмар за поддръжка от масивно дублиране на кодове и осиротели крайни точки, оставяйки ни с несъответствие.

Предимства на схема и система със строг тип

GraphQL използва стриктно, силна система от типове. Всички типове, форма на данните, които са изложени в API, се дефинират от схемата с помощта на езика за дефиниране на схема на GraphQL (SDL). Тази схема служи като силен договор за това как изглеждат операциите и за определяне дали заявката е валидна. с това схемата не само дефинира ресурсите, налични за извличане, но също така дефинира приетите параметри при извличане на данните. API на GraphQL са организирани по отношение на типове и полета, а не по крайни точки. Така клиентите могат да искат само това, което е възможно да се върне.

Сега, след като схемата е дефинирана, фронтенд и бекенд екипите могат да използват API без комуникация, тъй като и двамата са наясно с формата на данните, с които работят.

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

Документацията е първокласна характеристика на система GraphQL. Важно е да се гарантира, че услугите остават последователни, с техните възможности и така описанието на дефиницията на GraphQL се предоставя заедно с дефиницията в техните дефиниции и се предоставя чрез интроспекция, което я прави много четлива. Това е доста мощна способност, която позволява на дизайнерите на услуги лесно да описват и публикуват своята документация заедно с техните реализации.

Без повече API с версии

Развитието на REST API само по себе си е предизвикателство, с по-новите имплементации крайните точки трябва да се разменят, тъй като внедрените клиенти не могат да се счупят и с бързи цикли на освобождаване и гаранции за обратна съвместимост, приложенията ще имат голям брой версии на реализация на API, при такива ограничения е трудно да се премахнат данни от персонализирана крайна точка. Подобно на REST, полезните натоварвания на тези потребителски крайни точки нарастват монотонно с развитието на сървъра.

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

По-добра производителност и бърза итерация на интерфейса

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

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

REST е ДОБРЕ GraphQL е ПО-ДОБРЕ

Не че REST е напълно лош и ще умре по-рано, просто REST е по-скоро архитектурен стил, отколкото официален протокол. Всъщност има много дебат за това какво точно е REST и какво не е. С GraphQL ние представляваме нов начин за структуриране на договора клиент-сървър. Sever публикува специфична за приложението система от типове, GraphQL предоставя унифициран език за запитване на данните в рамките на определени ограничения на типовата система. Този език позволява на разработчиците да изразят своите точни изисквания за данни в декларативна и йерархична форма. REST може да живее дълго.

GraphQL е проектиран, като се имат предвид недостатъците и болката при проектирането, мащабирането и поддържането на REST API, с по-добра производителност, прецизен полезен товар, възможност за адаптиране, по-силна типова система и декларативен подход към извличането на данни GraphQL е по-добрият REST. От публичното си пускане през 2015 г. GraphQL бързо узря до точката, в която може да бъде адаптиран към почти всяка инфраструктура и архитектура. Общността, свързаната с нея софтуерна екосистема, както и адаптивността на компанията нараснаха с изключителна скорост. Компании като GitHub, Netflix, Airbnb, Coursera, New York Times, Shopify и много от тях вече са приели GraphQL в своите технологични стекове.

📚 Допълнителна информация и ресурси

👉 Тази публикация в блога първоначално беше публикувана в моя личен блог сайт

Свържете се

Хей, имате някакви предложения, въпроси или притеснения, не се колебайте да ми изпратите имейл. Можете също да ме намерите в Twitter, GitHub и LinkedIn. Помогнете ми да направя това по-добре, изпратете ми съобщение и аз ще се свържа с вас скоро! Благодаря!🎉