Ідэнтыфікацыя проты формы: Выбір параметраў маршруту чы рошэнняў запиту ў Express
Выявіце, калі значэнне паслужыць параметрам маршруту Express, а калі — часткай запиту, як чытаць req.params і req.query, а таксама як безпечна працаваць з стандартнымі значэннямі і типамі.
Возьміце URL /users/42?sort=name&order=asc. Чысло 42 пазначае конкрэтнага пользователя; параметры sort=name&order=asc толькі зменяюць спосаб аранжавання рэспонсу. Сумешчанне эйх двух функцый, напрыклад, выкарыстоўванне ID як фільтра чыста фільтра як ID, ёсць класычным выкарыстоўваннем, якое прыводзіць да проблем у маршрутах Express. Пасля чытання гіду у вас будзе просты тэст, які дапаможа ўхваліць, куды належы цяжэнне, і вы зразумеете, як Express адкрывае кожны тип такіх параметраў і якія неспадзянанні можна чакаць.
Параметры маршрута пазначаюць ресурс
Параметр маршрута — это імёнаваны фрагмент, які ўжо ўключаецца ў саму схему шляху. Ён паведамляе сервер, пра які самэль конкрэтны ресурс ідзе запит.
/users/:id
Знак двалітка пазначае :id як месца для заполнення. Калі прыходзіць запит на /users/42, Express падбягае за шаблонам і запісвае 42 як значэнне id. Тае ж правіло дапраўнае да будзь-каго ресурсу, які мае ідэнтыфікатор:
/users/42 → which user
/products/17 → which product
/orders/1042 → which order
Кожны з гэтых шляхоў пазначае толькі адну рэч. Без гэтага сегмента запытанне „каторы?“ не мае адпаведзення.
Строкі запытання формуюць адпаведзь
Строка запытання — это все, што знаходзіцца пасля ?: спіс пар key=value, з’едыненых символам &. Яна не выбірае ресурс; уместо таго яна фільтруе, сортавае, стварае сторніцаванне або іншым спосабам зменяе тое, што вяртаецца.
/users?sort=name&order=asc
У гэтым случае sort і order не зменяюць сам ресурс (колекцыю корыстнікаў) і толькі вплываюць на яго адображэнне. Болей типовыя прыклады:
/products?category=electronics&maxPrice=500
/search?q=laptop&page=2
Тэст з аднае запытаннем для разлічэння іх
Запытайце, што будзе, якшо вы удаліце значэнне:
- Якшо маршрут больш не мае сэнсу (вы не можете запрашваць „адного пользователя“ без указвання конкрэтнага), значэнне ўжо є ідэнтыфікатаром і паўіна належаць у шлях.
- Якшо маршрут продовжае працаваць і проста вяртае стандартны, нефільтруваны результат (усе корыстнікі, у стандартным порядку), значэнне ўжо є модыфікатаром і паўіна належаць у запытковую строчку.
Эты тэст таксама натыкае на кантроль выключэння адказоў. Відсутнае ресурса пасля параметра маршрута зазвычай апавярожана кодам 404, тады як фільтр, який нічога не падпадае пад критэрыя, зазвычай вяртае код 200 з порожнім спискам. Чырпаць больш дакладнае інфармацыю пра проектаванне URL, оріѐнтаванае на ресурсы, можна ў REST API для пачаткуючых.
Чытанне параметраў маршрута за дапамогою req.params
Параметры адыявляюцься за дапамою двалёкіх у шляху маршрута, а ўзятыя імі значэння выклікаюцца пад req.params пад тымі ж іменамі:
app.get("/users/:id", (req, res) => {
const userId = req.params.id;
res.send(`Fetching user with ID: ${userId}`);
});
Запрос да /users/42 ставіць req.params.id у значэнне строкі "42".
Калькі параметраў у аднам шляху
Узвышаныя рэсурсы проста адыявляюць больш месца для падстав:
app.get("/users/:userId/orders/:orderId", (req, res) => {
const { userId, orderId } = req.params;
res.send(`User ${userId}, Order ${orderId}`);
});
Для /users/42/orders/1042 дэструктурызацыя дае userId, які равнаеся "42", і orderId, які равнаеся "1042". Імены параметраў павінны быць унікальнымі ў межах маршрута, і яны павінны описваць тое, што адначасова ідэнтыфікуюць; userId і orderId чытваюцца набаго лепей, чым два ананімныя id.
Чытанне строк запита за дапамою req.query
Значэнняя запыткаў не патрабуюць адзінолькай дэкларацыі ў маршруце. Express парсуе все, што належыць пасля ?, і размешчае гэта на req.query:
app.get("/users", (req, res) => {
const { sort, order } = req.query;
res.send(`Sorting by ${sort}, order: ${order}`);
});
Для /users?sort=name&order=asc значэнне req.query.sort будзе "name", а значэнне req.query.order — "asc". Сам маршрут застаецца /users, таму адны і тыя ж обрабоўчыкі працуюць як з звычайным, так і з сортаваным запыткам.
Задаўненне стандартных значэнняя для необавязковых параметраў
Паколькі кліенты часта не падаюць значэнняя запыткаў, обрабоўчыкі зазвычай вяртаюцца да логічных стандартных значэнняў:
app.get("/products", (req, res) => {
const sort = req.query.sort || "default";
const page = req.query.page || 1;
res.send(`Sorting: ${sort}, Page: ${page}`);
});
Запрос простаю /products таксама выконваецца успешна, паводзячыся значэннямі-заменайкамі. Зважайце на адну тонкасць: калі кліент даклэў прышле page=2, то page будзе строкай "2", а калі яго не паказваць, то будзе цэлым числам 1. Такія сумешаныя типы пазней вызываюць багі (напрыклад, спалучэнне строкаў заместо адынавання). Акрасна перакладзіце значэнне, напрыклад, за дапамою Number(req.query.page) || 1, і пераканайцеся, што рэзультат правільны, прытымкі яго выкарыстоўваць у запытэ да базы дадзеных.
Значэння не завжды ў вачыні строкі
Ключ, які павтараецца ў URL, напрыклад ?tag=a&tag=b, прыходзіць у вазе масэвай, а не строкі. Залежна ад налашоўкі парсера запытання, синтаксі складоў таксама можа ствараць вярнутыя об’екты. Express 5 зменіў стандартны парсер на простышы, чым той, які викорыстоўваў Express 4, таму якщо вы павяржаецеся на вярнутыя об’екты запытання, пераканайцеся ў дасяглівых матэрыялах да вашай версіі. У будзь-якам случае ніколі не прыпускайце типу значэння запытання; спрыягайце req.query як ненадзеяны вхідны данный.
Выбір таго, калі яго патрабуе маршрут
Параметры шляху для конкрэтнага ресурсу
app.get("/users/:id", ...) // one specific user
app.get("/products/:id", ...) // one specific product
app.get("/orders/:orderId", ...) // one specific order
Кожны з эых маршрутаў аднасаецца да аднаго, конкрэтнага элемента. Якщо маршрут не мае сэнсу без гэтага значэння, падайце яго ў шлях.
Строкі запытання для фільтрацыі, сортавання і пагінацыі
app.get("/users", ...) // ?role=admin&status=active
app.get("/products", ...) // ?category=electronics&maxPrice=500&sort=price
app.get("/search", ...) // ?q=laptop&page=2
Кожны з эых варыянтаў застаецца зрозумелым без жадных запитоў: „все выкарыстоўчыкі“, „все тавары“ або порожняя стороніца пошуку. Значэнні, якія проста скарматываюць або пераранжуюць рэзультаты, ўсё ж такія ёсць неабавязковымі модифікаторамі і паўінны стаяць пасля ?.
Спалучэнне якіх-небудзь з іх у адной маршруце
Рэальныя канцэнтры часта викорыстоўваюць які-небудзь з іх адночасна. Параметр выбірае власніка, а запит скарматывае адпаведныя даны:
app.get("/users/:id/orders", (req, res) => {
const userId = req.params.id; // which user
const status = req.query.status; // optional filter: only their pending orders, for example
res.send(`Orders for user ${userId}, filtered by status: ${status || "all"}`);
});
Запрос да /users/42/orders?status=pending чытаецца прыродна: 42 пазначае, чыяя то замовленні, а status=pending — каторыя з тых замовленніў трэба включыць. Калі параметр status не паказваны, працоўнік обробкі дадае значэнне „все“, што адпавядае ідеі, што відсутнасць модифікатора означае нефільтраваны рэзультат.
Частыя запытанні
Можа адна маршруце викорыстоўваць які-небудзь з іх?
Так, і гэта дужа частая справа. Прыклад вышэй ёсць типовым шаблонам: ідэнтыфікатор для родныя рэсурса плюс неабяжлівыя фільтры для яго дзецей.
Чы роўнаймова неабяжлівы параметры, а значэння запиту — неабяжлівыя?
Гэта сильная прыемка, а не строгія правіла. Express падтрымляе неабяжлівыя сегменты шляху, і ніч не заважае API выкарыстоўваць неабяжлівыя значэння запиту. Тым часам практычныя рэкамендаціі застаюцца тымі ж: неабяжлівыя ідэнтыфікаторы ставяцца ў шлях, а неабяжлівыя модифікаторы — у запит з стандартнымі значэннямі.
Чы req.params.id — це число?
Нята. Усё, што выкарыстоўваецца з URL, ёсць строкай, нават калі выглядае як число. Адразу пераканвертаваць яго, напрыклад, за дапамою Number(req.params.id), і адхіліць значэнняя, якія станавяцца NaN, прычаму яшчэ не падключаючыся да базы даных.
Што, як не хватает прызначанага значэння запиту?
Ключ проста ўсунуты з req.query, таму яго чытанне дае undefined. Самэй гэтага стандартной практыкай єў выкарыстоўванне значэнняя-заместака, показаных раней.
Заключэнне
Оба відзелы даных знаходзяцца ў той самый URL, але вони выпалняюць разныя функцыі. Параметры маршрута, якія чытаны з req.params, называюць конкрэтны аб’ект, пра якій ідзе запит. Строкі запытаў, якія чытаны з req.query, вплываюць на спосаб фільтрацыі, сортавання чыста пагінавання рэсультаатаў, і ў яных павінны быць значэнняя-заместак. Спрыяйце да таго, каб які-небудзь з іх вважаліся строкамі без типу з зовнішняго света: ператварыце і прабавьце ўсё яныя пры выкарыстоўванні, і ваша структура маршрутаў застанется прыемлемай па мере росту API.
Спадні матэрыялы
- Захаванне межы Express: адні Zod-мідлвэр для тэла запыткі, параметраў і шаблона запыткі — Дазвольце вам дазнацца, як пераканаць правядзібнасць тэла запыткі Express, параметраў маршрута і шаблонаў запыткі за дапамогою аднаго віднаўляемага Zod-мідлвэра, а таксама як ён дапамагае у пераканаці правядзібнасці модэляў Sequelize.
- REST API для пачаткуючых: рэсурсы, методы, коды стану і абсэнція стану — Практычны падход да таго, што такое REST API, пяць прынцыпаў, якія яго робяць функцыйнальным, дзе ён викорыстоўваецца у рэальных командах, і як стварыць та працаваць з вашым першым REST API.