10 най-добри практики за писане на REST API на Node.js

В тази статия ние обхващаме най-добрите практики за писане на Node.js REST APIs, включително теми като именуване на вашите маршрути, удостоверяване, тестване в черни кутии и използване на подходящи заглавия на кеш за тези ресурси.

Един от най-популярните случаи на използване за Node.js е да пишете RESTful API, използвайки го. Все пак, докато помагаме на нашите клиенти да намерят проблеми в техните приложения с Trace, с нашия инструмент за наблюдение Node.js постоянно изпитваме, че разработчиците имат много проблеми с API на REST.

Надявам се, че тези най-добри практики, които използваме в RisingStack, могат да помогнат:

# 1: Използвайте HTTP методи и маршрути за API

Представете си, че изграждате Node.js RESTful API за създаване, актуализиране, извличане или изтриване на потребители. За тези операции HTTP вече разполага с адекватния набор от инструменти: POST, PUT, GET, PATCH или DELETE.

Като най-добра практика вашите маршрути за API винаги трябва да използват съществителни като идентификатори на ресурси. Говорейки за ресурсите на потребителя, маршрутизацията може да изглежда така:

  • POST / потребител или PUT / user: / id за създаване на нов потребител,
  • GET / потребител за извличане на списък с потребители,
  • GET / user /: id за извличане на потребител,
  • PATCH / потребител /: id за промяна на съществуващ потребителски запис,
  • DELETE / user /: id за премахване на потребител.

# 2: Използвайте правилно кодовете на HTTP състоянието

Ако нещо се обърка по време на подаване на заявка, трябва да зададете правилния код на състоянието за това в отговора:

  • 2xx, ако всичко беше наред,
  • 3xx, ако ресурсът е преместен,
  • 4xx, ако заявката не може да бъде изпълнена поради клиентска грешка (като искане на ресурс, който не съществува),
  • 5xx, ако нещо се обърка от страна на API (като изключение се случи).

Ако използвате Express, задаването на кода на състоянието е толкова лесно, колкото res.status (500) .send ({грешка: „Възникна вътрешна грешка в сървъра“}). Подобно е и с Restify: res.status (201).

За пълен списък, проверете списъка на кодовете на състоянието на HTTP

# 3: Използвайте HTTP заглавки за изпращане на метаданни

За да прикачите метаданни за полезния товар, който ще изпратите, използвайте HTTP заглавки. Заглавки като тази могат да бъдат информация за:

  • страниране,
  • ограничаване на процента,
  • или удостоверяване

Списък на стандартизирани HTTP заглавки можете да намерите тук.

Ако трябва да зададете някакви персонализирани метаданни в заглавките си, беше най-добра практика да ги префиксирате с X. Например, ако използвате маркери CSRF, това беше често срещан (но нестандартен) начин да ги назовавате X-Csrf -Token. Въпреки това с RFC 6648 те са остарели. Новите API трябва да положат всички усилия да не използват имена на заглавия, които могат да противоречат на други приложения. Например, OpenStack префиксира заглавките си с OpenStack:

OpenStack-Identity-Account-ID
OpenStack-Networking-домакин-Наименование
OpenStack-Object-съхранение-политика

Обърнете внимание, че стандартът HTTP не определя ограничение на размера на заглавките; Въпреки това, Node.js (към писането на тази статия) налага ограничение за размер на 80KB на обекта заглавки по практически причини.

„Не позволявайте общият размер на HTTP заглавките (включително реда на състоянието) да надвишава HTTP_MAX_HEADER_SIZE. Тази проверка е тук, за да защити вградените файлове срещу атаки за отказ на услуга, при които нападателят ни захранва безкраен заглав, който вградителят продължава да буферира. "
От HTTP анализатора на Node.js

# 4: Изберете правилната рамка за вашия Node.js REST API

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

Експрес, Коа или Хапи

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

Restify

От друга страна, Restify се фокусира върху това да ви помогне да изградите REST услуги. Съществува, за да ви позволи да изградите „строги“ API услуги, които са поддържани и наблюдавани. Restify също се предлага с автоматична поддръжка на DTrace за всички ваши обработващи устройства.

Restify се използва в производството в големи приложения като npm или Netflix.

# 5: Black-Box Тествайте вашите Node.js REST API

Един от най-добрите начини за тестване на вашите REST API е да ги третирате като черни кутии.

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

Един от модулите, които могат да ви помогнат при тестване на черни кутии Node.js REST APIs е супертест.

Един прост тестов случай, който проверява дали потребителят е върнат с помощта на тестовия моникър за изпълнение може да бъде реализиран така:

const заявка = изисквам ("супертест")
 
description ('GET / user /: id', function () {
  it ('връща потребител ", функция () {
    // по-новите версии на мока също приема обещания
    заявка за връщане (приложение)
      .get ( '/ на потребителя)
      .set ('Приемам', 'application / json')
      .очаквайте (200, {
        id: '1',
        име: „Джон Мат“
      }, Свършен)
  })
})

Може да попитате: как данните се попълват в базата данни, която обслужва REST API?

Като цяло е добър подход да напишете своите тестове по начин, по който те правят възможно най-малко предположения за състоянието на системата. И все пак в някои сценарии можете да се окажете на място, когато трябва да знаете точно какво е състоянието на системата, така че можете да правите твърдения и да постигате по-голямо покритие на теста.

Така въз основа на вашите нужди можете да попълните базата данни с тестови данни по един от следните начини:

  • пуснете своите тестови сценарии в черно поле на известен подмножество от производствени данни,
  • попълнете базата данни с изработени данни, преди тестовите случаи да бъдат стартирани.

Разбира се, тестването в черни кутии не означава, че не е нужно да правите тестване на единици, все пак трябва да напишете единични тестове за своите API.

# 6: Направете JWT основаване на удостоверяване без гражданство

Тъй като вашите REST API трябва да са без гражданство, така и вашият слой за удостоверяване. За това JWT (JSON Web Token) е идеален.

JWT се състои от три части:

  • Заглавка, съдържаща типа на маркера и алгоритъма на хеширане
  • Полезен товар, съдържащ претенциите
  • Подпис (JWT не криптира полезния товар, а просто го подписва!)

Добавянето на JWT автентификация към приложението ви е много лесно:

const koa = изисквам ('koa')
const jwt = изисквам ('koa-jwt')
приложение const = koa ()
app.use (JWT ({
  тайна: „много тайна“
}))
// Защитен междинен софтуер
app.use (функция * () {
  // съдържанието на маркера ще бъде достъпно на this.state.user
  this.body = {
    тайна: '42'
  }
})

След това крайните точки на API са защитени с JWT. За достъп до защитените крайни точки трябва да предоставите маркера в полето за оторизация.

curl --header "Разрешение: Носител eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30
RMHrHDcEfxjoYZgeFONFh7HgQ "my-website.com

Едно нещо, което можете да забележите, е, че JWT модулът не зависи от никой слой от база данни. Това е така, защото всички JWT маркери могат да бъдат проверявани самостоятелно, а също така могат да съдържат време за живи стойности.

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

В предишна статия обяснихме подробно методите за удостоверяване на уеб - препоръчвам да го проверите!

# 7: Използвайте условни заявки

Условните заявки са HTTP заявки, които се изпълняват различно в зависимост от конкретни HTTP заглавки. Можете да мислите за тези заглавия като предпоставки: ако те са изпълнени, заявките ще бъдат изпълнени по различен начин.

Тези заглавия се опитват да проверят дали версия на ресурс, съхранявана на сървъра, съвпада с дадена версия на същия ресурс. Поради тази причина, тези заглавки могат да бъдат:

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

Тези заглавия са:

  • Последна промяна (за да посочи кога ресурсът е последно променен),
  • Etag (за да посочите етикета на субекта),
  • Ако е модифициран-тъй като (използва се с заглавката с последна промяна),
  • If-None-Match (използва се с заглавката на Etag),

Нека да разгледаме пример!

Клиентът по-долу нямаше предишни версии на ресурса на doc, така че нито заглавието If-Modified-Since, нито If-None-Match е приложено при изпращане на ресурса. След това сървърът отговаря с правилно настроените заглавия Etag и Last-Modified.

От документацията за условно искане на MDN

Клиентът може да зададе заглавките If-Modified-Since и If-None-Match, след като се опита да поиска същия ресурс - тъй като вече има версия. Ако отговорът би бил същият, сървърът просто отговаря със състоянието 304 - Not Modified и не изпраща ресурса отново.

От документацията за условно искане на MDN

# 8: Ограничаване на скоростта на възприемане

Ограничаването на скоростта се използва за контролиране на това колко искания може да изпрати потребител към API.

За да кажете на вашите потребители на API колко искания са останали, задайте следните заглавия:

  • X-Rate-Limit-Limit - броя на разрешените искания в даден времеви интервал
  • X-Rate-Limit-Остава, броят на исканията, оставащи в същия интервал,
  • X-Rate-Limit-Нулиране, времето, когато лимитът на скоростта ще бъде нулиран.

Повечето HTTP рамки го поддържат извън кутията (или с приставки). Например, ако използвате Koa, съществува пакетът koa-ratelimit.

Имайте предвид, че времевият прозорец може да варира в зависимост от различни доставчици на API - например GitHub използва час за това, докато Twitter 15 минути.

# 9: Създаване на правилна API документация

Вие пишете API, за да могат другите да ги използват, да се възползват от тях. Предоставянето на API документация за вашите Node.js REST APIs са от решаващо значение.

Следните проекти с отворен код могат да ви помогнат при създаването на документация за вашите API-та:

  • API план
  • перчене

Освен това, ако искате да използвате хоствани продукти, можете да отидете за Apiary.

# 10: Не пропускайте бъдещето на API

През изминалите години възникнаха два основни езика за заявки за API - а именно GraphQL от Facebook и Falcor от Netflix. Но защо дори имаме нужда от тях?

Представете си следната заявка за RESTful ресурс:

/ Org / 1 / пространство / 2 / документи / 1 / сътрудници?
включва = имейл & страница = 1 & лимит = 10

Това може да се измъкне от ръката доста лесно - както искате да получавате един и същ формат за отговор за всичките си модели през цялото време. Тук GraphQL и Falcor могат да помогнат.

За GraphQL

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

Относно Falcor

Falcor е иновативната платформа за данни, която захранва потребителските интерфейси на Netflix. Falcor ви позволява да моделирате всичките си резервни данни като единичен виртуален JSON обект на вашия сървър на Node. На клиента работите с отдалечения си JSON обект, като използвате познати операции на JavaScript като get, set и call. Ако знаете вашите данни, знаете вашия API. - Прочетете повече тук.

Невероятни API за REST за вдъхновение

Ако сте на път да започнете да разработвате Node.js REST API или да създадете нова версия на по-стара, ние събрахме четири примера от реалния живот, които си струва да проверите:

  • GitHub API
  • API на Twilio
  • API на Stripe
  • API на DigitalOcean

Надявам се, че сега имате по-добро разбиране за това как трябва да се пишат API-тата с помощта на Node.js. Моля, уведомете ме в коментарите, ако пропуснете нещо!

Първоначално публикуван на blog.risingstack.com на 21 февруари 2017 г.