portaldacalheta.pt
  • Главни
  • Агиле Талент
  • Финансијски Процеси
  • Дизајн Бренда
  • Трендови
Бацк-Енд

Изградња Ноде.јс / ТипеСцрипт РЕСТ АПИ-ја, 1. део: Екпресс.јс



Како да напишем РЕСТ АПИ у Ноде.јс?

Када се прави позадина за РЕСТ АПИ, Екпресс.јс је често први избор међу Ноде.јс оквирима. Иако такође подржава изградњу статичког ХТМЛ-а и шаблона, у овој серији ћемо се фокусирати на позадински развој користећи ТипеСцрипт. Добијени РЕСТ АПИ ће бити онај који би било који фронт-енд фрамеворк или екстерни бацк-енд сервис могао да тражи.

Мораћете:



  • Основно знање ЈаваСцрипт-а и ТипеСцрипт-а
  • Основно знање о Ноде.јс
  • Основно знање о РЕСТ архитектури (уп. овај одељак мог претходног РЕСТ АПИ чланка ако је потребно)
  • Спремна инсталација Ноде.јс (пожељно верзија 14+)

У терминалу (или командној линији) направићемо фасциклу за пројекат. Из те фасцикле покрените npm init. То ће створити неке од основних датотека Ноде.јс пројекта које су нам потребне.



Следеће ћемо додати Екпресс.јс оквир и неке корисне библиотеке:



npm install --save express debug winston express-winston cors

Постоје добри разлози због којих су ове библиотеке Ноде.јс програмер фаворити:

  • debug је модул који ћемо користити да избегнемо позивање console.log() док развијамо нашу апликацију. На овај начин лако можемо филтрирати изјаве за отклањање грешака током решавања проблема. Такође се могу у потпуности искључити у производњи, уместо да их треба ручно уклањати.
  • winston одговоран је за евидентирање захтева за наш АПИ и враћене одговоре (и грешке). express-winston интегрише се директно са Екпресс.јс, тако да сви стандардни АПИ-ји winston код за евидентирање је већ завршен.
  • cors је део Екпресс.јс посредничког софтвера који нам омогућава да то омогућимо дељење ресурса више порекла . Без тога би наш АПИ био употребљив само са предњих крајева који се сервирају са потпуно исте поддомене као и са наше задње стране.

Наш задњи крај користи ове пакете када је покренут. Али такође морамо инсталирати неке развој зависности за нашу ТипеСцрипт конфигурацију. За то ћемо покренути:



npm install --save-dev @types/cors @types/express @types/debug source-map-support tslint typescript

Ове зависности су потребне да би се омогућио ТипеСцрипт за сопствени код наше апликације, заједно са типовима које користи Екпресс.јс и друге зависности. Ово може уштедети пуно времена када користимо ИДЕ попут ВебСторм или ВСЦоде, омогућавајући нам да аутоматски довршимо неке функције током кодирања.

Коначне зависности у package.json треба да буде овако:



'dependencies': { 'debug': '^4.2.0', 'express': '^4.17.1', 'express-winston': '^4.0.5', 'winston': '^3.3.3', 'cors': '^2.8.5' }, 'devDependencies': { '@types/cors': '^2.8.7', '@types/debug': '^4.1.5', '@types/express': '^4.17.2', 'source-map-support': '^0.5.16', 'tslint': '^6.0.0', 'typescript': '^3.7.5' }

Сада када смо инсталирали све потребне зависности, кренимо да правимо сопствени код!

Структура пројекта ТипеСцрипт РЕСТ АПИ

За ово упутство ћемо створити само три датотеке:



  1. ./app.ts
  2. ./common/common.routes.config.ts
  3. ./users/users.routes.config.ts

Идеја иза две фасцикле структуре пројекта (common и users) је да имају појединачне модуле који имају своје одговорности. У том смислу, на крају ћемо имати неке или све следеће за сваки модул:

  • Конфигурација руте да дефинишемо захтеве које наш АПИ може да обради
  • Услуге за задатке попут повезивања са нашим моделима базе података, израде упита или повезивања са спољним услугама које су потребне у одређеном захтеву
  • Миддлеваре за покретање валидација специфичних захтева пре него што коначни контролор руте обради његове специфичности
  • Модели за дефинисање модела података који се подударају са датом шемом базе података, како би се олакшало складиштење и проналажење података
  • Контролери за одвајање конфигурације руте од кода који коначно (након било ког међуопреме) обрађује захтев за рутом, по потреби позива горње функције услуге и даје одговор клијенту

Ова структура директоријума пружа рану полазну тачку за остатак овог упутства и довољно за почетак вежбања.



Датотека уобичајених рута у ТипеСцрипт-у

У common , креирајмо common.routes.config.ts датотека да изгледа овако:

import express from 'express'; export class CommonRoutesConfig { app: express.Application; name: string; constructor(app: express.Application, name: string) { this.app = app; this.name = name; } getName() { return this.name; } }

Начин на који овде креирамо руте није обавезан. Али пошто радимо са ТипеСцрипт-ом, сценарио наших рута је прилика да вежбамо коришћење наследства са extends кључна реч, као што ћемо видети ускоро. У овом пројекту, све датотеке руте имају исто понашање: Имају име (које ћемо користити за уклањање грешака) и приступ главном Екпресс.јс Application објект.



Сада можемо започети са креирањем датотеке корисника. На users директоријум, креирајмо users.routes.config.ts и почните да га кодирате овако:

import {CommonRoutesConfig} from '../common/common.routes.config'; import express from 'express'; export class UsersRoutes extends CommonRoutesConfig { constructor(app: express.Application) { super(app, 'UsersRoutes'); } }

Ево, увозимо CommonRoutesConfig класе и проширујући је на нашу нову класу, која се зове UsersRoutes. Са конструктором шаљемо апликацију (главни express.Application објекат) и име УсерсРоутес конструктору CommonRoutesConfig

Овај пример је прилично једноставан, али када скалирамо како бисмо створили неколико датотека руте, ово ће нам помоћи да избегнемо дуплирани код.

Претпоставимо да бисмо желели да у ову датотеку додамо нове функције, као што је евидентирање. Могли бисмо додати потребно поље у CommonRoutesConfig класе, а затим све руте које се протежу CommonRoutesConfig имаће приступ.

утицај боје на људско понашање

Коришћење апстрактних функција ТипеСцрипт за сличне функционалности током класа

Шта ако бисмо желели да имамо неку функционалност која је слично између ових класа (попут конфигурисања АПИ крајњих тачака), али за то је потребна различита имплементација за сваку класу? Једна од могућности је употреба ТипеСцрипт функције тзв одвајање .

Направимо врло једноставну апстрактну функцију која UsersRoutes класа (и будуће класе рутирања) наследиће од CommonRoutesConfig. Рецимо да желимо да присилимо све руте да имају функцију (тако да је можемо назвати из нашег заједничког конструктора) која се зове configureRoutes(). Ту ћемо прогласити крајње тачке ресурса сваке класе рутирања.

Да бисмо то урадили, додаћемо три брзе ствари у common.routes.config.ts:

  1. Кључна реч abstract до нашег class линија, како би се омогућила апстракција за ову класу.
  2. Нова декларација функције на крају наше класе, abstract configureRoutes(): express.Application;. Ово присиљава било коју класу која се протеже CommonRoutesConfig да обезбеди имплементацију која се подудара са тим потписом - ако се не догоди, преводилац ТипеСцрипт ће избацити грешку.
  3. Позив на this.configureRoutes(); на крају конструктора, јер сада можемо бити сигурни да ће ова функција постојати.

Резултат:

import express from 'express'; export abstract class CommonRoutesConfig { app: express.Application; name: string; constructor(app: express.Application, name: string) { this.app = app; this.name = name; this.configureRoutes(); } getName() { return this.name; } abstract configureRoutes(): express.Application; }

Уз то, било која класа која се протеже CommonRoutesConfig мора имати функцију која се зове configureRoutes() који враћа express.Application објект. То значи users.routes.config.ts треба ажурирати:

import {CommonRoutesConfig} from '../common/common.routes.config'; import express from 'express'; export class UsersRoutes extends CommonRoutesConfig { constructor(app: express.Application) { super(app, 'UsersRoutes'); } configureRoutes() { // (we'll add the actual route configuration here next) return this.app; } }

Као резиме онога што смо направили:

Прво увозимо common.routes.config датотека, затим express модул. Затим дефинишемо UserRoutes класе, рекавши да желимо да прошири CommonRoutesConfig основна класа, што подразумева да обећавамо да ће применити configureRoutes().

Да бисте послали информације на CommonRoutesConfig класе, користимо constructor разреда. Очекује да ће добити express.Application објекта, што ћемо детаљније описати у следећем кораку. Са super() прелазимо на конструктор CommonRoutesConfig апликације и име наших рута, што је у овом сценарију УсерсРоутес. (super(), заузврат, позваће нашу имплементацију configureRoutes().)

Конфигурисање Екпресс.јс рута крајњих тачака корисника

Тхе configureRoutes() функција је место где ћемо створити крајње тачке за кориснике нашег РЕСТ АПИ-ја. Тамо ћемо користити апликација и његове рута функционалности из Екпресс.јс.

Идеја у коришћењу app.route() функција је да се избегне дуплирање кода, што је лако јер креирамо РЕСТ АПИ са добро дефинисаним ресурсима. Главни ресурс овог водича је корисника . У овом сценарију имамо два случаја:

  • Када АПИ позивалац жели да креира новог корисника или да наведе све постојеће кориснике, крајња тачка би у почетку требала имати само users на крају тражене путање. (У овом чланку нећемо улазити у филтрирање упита, пагинацију или друге такве упите.)
  • Када позивалац жели да уради нешто специфично за одређени кориснички запис, путања ресурса захтева следи образац users/:userId

Начин .route() ради у Екпресс.јс-у омогућава нам руковање ХТТП глаголима са неким елегантним уланчавањем. То је зато што .get(), .post(), итд., Враћају исту инстанцу IRoute да је први .route() цалл доес. Коначна конфигурација биће овако:

configureRoutes() { this.app.route(`/users`) .get((req: express.Request, res: express.Response) => { res.status(200).send(`List of users`); }) .post((req: express.Request, res: express.Response) => { res.status(200).send(`Post to users`); }); this.app.route(`/users/:userId`) .all((req: express.Request, res: express.Response, next: express.NextFunction) => { // this middleware function runs before any request to /users/:userId // but it doesn't accomplish anything just yet--- // it simply passes control to the next applicable function below using next() next(); }) .get((req: express.Request, res: express.Response) => { res.status(200).send(`GET requested for id ${req.params.userId}`); }) .put((req: express.Request, res: express.Response) => { res.status(200).send(`PUT requested for id ${req.params.userId}`); }) .patch((req: express.Request, res: express.Response) => { res.status(200).send(`PATCH requested for id ${req.params.userId}`); }) .delete((req: express.Request, res: express.Response) => { res.status(200).send(`DELETE requested for id ${req.params.userId}`); }); return this.app; }

Горњи код омогућава било ком клијенту РЕСТ АПИ да позове наш users крајња тачка са POST или а GET захтев. Слично томе, омогућава клијенту да позове наш /users/:userId крајња тачка са GET, PUT, PATCH или DELETE захтев.

Али за /users/:userId, додали смо и генерички посреднички софтвер помоћу all() функција која ће се покретати пре било ког од get(), put(), patch() или delete() функције. Ова функција ће бити корисна када (касније у серији) креирамо руте којима је намењен приступ само овјереним корисницима.

Можда сте то приметили у нашем .all() функција - као и код било ког дела посредничког софтвера - имамо три врсте поља: Request, Response и NextFunction.

  • Тхе Захтев је начин на који Екпресс.јс представља ХТТП захтев којим треба руковати. Овај тип надограђује и проширује изворни Ноде.јс Врста Захтева.
  • Тхе Одговор је на исти начин како Екпресс.јс представља ХТТП одговор, поново проширујући изворни Ноде.јс тип одговора.
  • Ништа мање важно, NextFunction служи као функција повратног позива, омогућавајући контроли да пролази кроз било које друге функције међуопреме. Успут, сав посреднички софтвер ће делити исти објекат захтева и одговора пре него што контролер коначно пошаље одговор подносиоцу захтева.

Наша датотека улазне тачке Ноде.јс, app.ts

Сада када смо конфигурисали неке основне скелете рута, започет ћемо конфигурисање улазне тачке апликације. Створимо app.ts датотеку у корену фасцикле нашег пројекта и започните је овим кодом:

import express from 'express'; import * as http from 'http'; import * as bodyparser from 'body-parser'; import * as winston from 'winston'; import * as expressWinston from 'express-winston'; import cors from 'cors'; import {CommonRoutesConfig} from './common/common.routes.config'; import {UsersRoutes} from './users/users.routes.config'; import debug from 'debug';

Само два од ових увоза су нова у овом тренутку у чланку:

  • http је Ноде.јс-изворни модул. Потребно је да покренете нашу Екпресс.јс апликацију.
  • body-parser је међуопрема која долази са Екпресс.јс. Анализира захтев (у нашем случају као ЈСОН) пре него што контрола пређе на наше властите обрађиваче захтева.

Сада када смо увезли датотеке, почећемо да декларишемо променљиве које желимо да користимо:

извештај о токовима готовине из биланса стања
const app: express.Application = express(); const server: http.Server = http.createServer(app); const port: Number = 3000; const routes: Array = []; const debugLog: debug.IDebugger = debug('app');

Тхе express() функција враћа главни објект Екпресс.јс апликације који ћемо проћи кроз наш код, почевши од додавања у http.Server објект. (Морат ћемо покренути http.Server након конфигурације нашег express.Application.)

Слушаћемо на порту 3000 уместо на стандардним портовима 80 (ХТТП) или 443 (ХТТПС), јер би се они обично користили за предњи крај апликације.

Зашто Порт 3000?

Не постоји правило да лука треба бити 3000 - ако није одређено, произвољна лука биће додељено - али 3000 се користи у примерима документације и за Ноде.јс и за Екпресс.јс, тако да овде настављамо традицију.

Може ли Ноде.јс да дели портове са предњим крајем?

И даље можемо локално да радимо на прилагођеном порту, чак и када желимо да наш задњи крај одговара на захтеве на стандардним портовима. Ово би захтевало обрнути прокси за пријем захтева на порт 80 или 443 са одређеним доменом или поддоменом. Затим би их преусмерио на наш интерни порт 3000.

Тхе routes арраи ће пратити датотеке наших рута у сврхе отклањања грешака, као што ћемо видети у наставку.

Коначно, debugLog завршиће као функција слична console.log, али боље: Лакше је фино подесити јер се аутоматски поставља у опсег на оно што желимо да зовемо контекст датотеке / модула. (У овом случају, назвали смо га „апликација“ када смо то проследили у низу конструктору debug()).)

Сада смо спремни да конфигуришемо све наше Екпресс.јс модуле међуопреме и руте нашег АПИ-ја:

// here we are adding middleware to parse all incoming requests as JSON app.use(bodyparser.json()); // here we are adding middleware to allow cross-origin requests app.use(cors()); // here we are configuring the expressWinston logging middleware, // which will automatically log all HTTP requests handled by Express.js app.use(expressWinston.logger({ transports: [ new winston.transports.Console() ], format: winston.format.combine( winston.format.colorize(), winston.format.json() ) })); // here we are adding the UserRoutes to our array, // after sending the Express.js application object to have the routes added to our app! routes.push(new UsersRoutes(app)); // here we are configuring the expressWinston error-logging middleware, // which doesn't *handle* errors per se, but does *log* them app.use(expressWinston.errorLogger({ transports: [ new winston.transports.Console() ], format: winston.format.combine( winston.format.colorize(), winston.format.json() ) })); // this is a simple route to make sure everything is working properly app.get('/', (req: express.Request, res: express.Response) => { res.status(200).send(`Server up and running!`) });

Можда сте приметили да expressWinston.errorLogger је постављено после ми дефинишемо наше руте. Ово није грешка! Као екпресс-винстон документација државе:

Регистратор треба додати НАКОН експресног рутера (app.router) И ПРЕД било којим од ваших прилагођених руковалаца грешкама (express.handler).

Коначно и најважније:

server.listen(port, () => { debugLog(`Server running at http://localhost:${port}`); routes.forEach((route: CommonRoutesConfig) => { debugLog(`Routes configured for ${route.getName()}`); }); });

Ово заправо покреће наш сервер. Једном када је покренуто, Ноде.јс ће покренути нашу функцију повратног позива која извештава да радимо, праћена именима свих рута које смо конфигурисали - до сада, само UsersRoutes

Ажурирање package.json на Транспиле ТипеСцрипт у ЈаваСцрипт и покрените апликацију

Сада када имамо свој скелет спреман за рад, прво нам је потребна нека конфигурација узорка да би се омогућила ТипеСцрипт транспилација. Додајмо датотеку tsconfig.json у корену пројекта:

{ 'compilerOptions': { 'target': 'es2016', 'module': 'commonjs', 'outDir': './dist', 'strict': true, 'esModuleInterop': true, 'inlineSourceMap': true } }

Тада само треба да додамо последње потезе у package.json у облику следећих скрипти:

'scripts': { 'start': 'tsc && node ./dist/app.js', 'debug': 'export DEBUG=* && npm run start', 'test': 'echo 'Error: no test specified' && exit 1' },

Тхе test скрипта је резервирано место које ћемо заменити касније у низу.

Тхе тсц у start скрипта припада ТипеСцрипт-у. Одговоран је за превођење нашег ТипеСцрипт кода у ЈаваСцрипт, који ће избацити у dist директоријум. Затим само покрећемо уграђену верзију са node ./dist/app.js.

Тхе debug скрипта позива start скрипта, али прво дефинише DEBUG променљива околине. Ово има за последицу омогућавање свих наших debugLog() изјаве (плус сличне из самог Екпресс.јс-а, који користи исти debug модул као и ми) за излаз корисних детаља на терминал - детаље који се (погодно) иначе скривају приликом покретања сервера у производном режиму са стандардним npm start.

Покушајте да покренете npm run debug себе, а затим упоредите то са npm start да бисте видели како се мења излаз конзоле.

Савет: Излаз за отклањање грешака можете ограничити на наш app.ts датотека је сопствена debugLog() изјаве помоћу DEBUG=app уместо DEBUG=*. Тхе debug модул је генерално прилично флексибилан и ова функција није изузетак .

Корисници Виндовс-а ће вероватно морати да промене export до SET пошто export је како то функционише на Мац-у и Линук-у. Ако ваш пројекат треба да подржи више развојних окружења, цросс-енв пакет овде пружа директно решење.

Тестирање позадине Ливе Екпресс.јс

Са npm run debug или npm start још увек траје, наш РЕСТ АПИ биће спреман за сервисирање захтева на порту 3000. У овом тренутку можемо да користимо цУРЛ, Поштар , Несаница итд. за тестирање задњег дела.

Будући да смо креирали само скелет за кориснички ресурс, можемо једноставно да шаљемо захтеве без тела да бисмо видели да ли све функционише како се очекује. На пример:

curl --location --request GET 'localhost:3000/users/12345'

Наш задњи крај би требало да пошаље одговор GET requested for id 12345.

Што се тиче POST инг:

curl --location --request POST 'localhost:3000/users' --data-raw ''

Овај и сви други типови захтева за које смо направили скелете изгледаће прилично слично.

Спреман за Рапид Ноде.јс РЕСТ АПИ развој са ТипеСцрипт-ом

У овом чланку започели смо са креирањем РЕСТ АПИ-ја конфигурисањем пројекта од нуле и роњењем у основе Екпресс.јс оквира. Затим смо направили први корак ка савладавању ТипеСцрипт-а градећи образац са UsersRoutesConfig продужавајући CommonRoutesConfig, образац који ћемо поново користити за следећи чланак из ове серије. Завршили смо конфигурисањем наших app.ts улазна тачка за коришћење наших нових рута и package.json са скриптама за изградњу и покретање наше апликације.

Али чак су и основе РЕСТ АПИ-ја направљене помоћу Екпресс.јс и ТипеСцрипт прилично укључене. У следећи део ове серије фокусирамо се на стварање одговарајућих контролера за корисничке ресурсе и истражујемо неке корисне обрасце за услуге, међуопреме, контролере и моделе.

јавасцрипт добија датум у милисекундама

Комплетан пројекат је доступан на ГитХуб-у , а код на крају овог чланка налази се у toptal-article-01 грана.

Разумевање основа

Могу ли да користим ТипеСцрипт са Ноде.јс?

Апсолутно! Веома је уобичајено да популарни нпм пакети (укључујући Екпресс.јс) имају одговарајуће датотеке дефиниције типа ТипеСцрипт. Ово важи за сам Ноде.јс, плус укључене поткомпоненте попут његовог пакета за отклањање грешака.

Да ли је Ноде.јс добар за РЕСТ АПИ-је?

Да. Ноде.јс се сам може користити за креирање РЕСТ АПИ-ја спремних за производњу, а постоји и неколико популарних оквира попут Екпресс.јс за смањење неизбежног бојлера.

Да ли је ТипеСцрипт тешко научити?

Не, није тешко започети учење ТипеСцрипт-а онима који имају модерну ЈаваСцрипт позадину. Још је лакше онима који имају искуства у објектно оријентисаном програмирању. Али савладавање свих ТипеСцрипт-ових нијанси и најбољих пракси захтева време, као и свака вештина.

Да ли треба да користим ТипеСцрипт?

Зависи од пројекта, али се дефинитивно препоручује за програмирање Ноде.јс. То је изражајнији језик за моделирање стварних домена проблема на задњем крају. То чини код читљивијим и смањује потенцијал за грешке.

За шта се користи ТипеСцрипт?

ТипеСцрипт се користи свуда где се ЈаваСцрипт налази, али је посебно погодан за веће апликације. Користи ЈаваСцрипт као основу, додајући статичко куцање и много бољу подршку за парадигму објектно оријентисаног програмирања (ООП). Ово заузврат подржава напредније искуство у развоју и отклањању грешака.

Моћнији, срећнији, продуктивнији - студија случаја вештачке интелигенције

Дистрибуирани Тимови

Моћнији, срећнији, продуктивнији - студија случаја вештачке интелигенције
Поравнати се за успех - Водич кроз оно што инвеститори траже у стартупу

Поравнати се за успех - Водич кроз оно што инвеститори траже у стартупу

Финансијски Процеси

Популар Постс
Како створити бот за анализу расположења е-поште: Водич за НЛП.
Како створити бот за анализу расположења е-поште: Водич за НЛП.
Поуке из инвестиционе стратегије Варрена Буффетта и његове грешке
Поуке из инвестиционе стратегије Варрена Буффетта и његове грешке
Зашто отплата дељења не успева? Неки предложени лекови
Зашто отплата дељења не успева? Неки предложени лекови
Повећајте своју продуктивност помоћу Амазон Веб Сервицес
Повећајте своју продуктивност помоћу Амазон Веб Сервицес
Развој Андроид ТВ-а - Долазе велики екрани, припремите се!
Развој Андроид ТВ-а - Долазе велики екрани, припремите се!
 
Доступност на мрежи: зашто се стандарди В3Ц често игноришу
Доступност на мрежи: зашто се стандарди В3Ц често игноришу
Алати наредбеног ретка за програмере
Алати наредбеног ретка за програмере
Зен девРант-а
Зен девРант-а
Заступства и гаранција: Алат за спајања и преузимања о коме би сваки продавац требао знати
Заступства и гаранција: Алат за спајања и преузимања о коме би сваки продавац требао знати
Значај дизајна усмереног на човека у дизајну производа
Значај дизајна усмереног на човека у дизајну производа
Популар Постс
  • прави хаковани бројеви кредитних картица
  • како бисте водили интервјуе са корисницима да покушавате да тестирате одређену интеракцију?
  • аппле паи за андроид кориснике
  • калкулатор за поређење в2 и 1099
  • тужна панда грешка при рашчлањивању странице резултата пријаве
Категорије
  • Агиле Талент
  • Финансијски Процеси
  • Дизајн Бренда
  • Трендови
  • © 2022 | Сва Права Задржана

    portaldacalheta.pt