Ладони потные, слабые колени, руки тяжелые,
У его Патагуччи уже есть рвота
Это те виды технических вопросов интервью, которые мои друзья говорили мне о том, что это заставило бы меня заморозить. То, как его сформулировано, кажется такой большой работой и скрытой сложности. И я уверен, что есть — если вы действительно хотели выбить его из парка — но сегодня, примерно через 4 часа в задаче, которая я нашел более раздражающим, чем сложным, я понял, что сделаю именно это (вроде как , на очень низком уровне).
Источник изображения заголовка
T, почему вы создали пользовательский маршрутизатор?
Это великий Вопрос, я рад, что вы спросили 🕺🏽.
ТАК
В настоящее время я работаю над проектом, где мы создаем кучу детских API для CRUD (создать, извлекать, обновить, удалить) некоторые вещи из таблиц DynamoDB. Из кучи причин, не в последнюю очередь, включая тот факт, что Я единственный инженер В этом проекте — я пытаюсь Выиграйте продажи, зарабатывайте бонусы и зарабатывайте деньги Двигайтесь быстро и поддерживайте как можно меньше «живой инфраструктуры».
Из -за этого я пришел к следующим выводам/решениям о том, как я буду продолжать:
Устал 😰
- Запуск node.js WebServer (и связанный с этим инфраю и управление) для эффективного брокера CRUD запросы в DynamoDB?
Проводной ☕
- Настройка шлюза AWS API, который запустил бы лямбду, чтобы разорвать необходимые вещи из DynamoDB Проводной
Мы $ erverle $$ baaaabyyyyyyyyyyyyyyyyyyyyyy
Вдохновлен ✨
В любом случае, TL: DR на этом состоит в том, что будет Gateway API, который получает HTTP -запросы, а затем отправляет их на функцию лямбды, которая решает, как справиться с запросом, прежде чем поднять взаимодействие с DynamoDB.
У меня есть один набор ресурсов Проекты
Это существует в таблице DynamoDB (в одном Проекты
), и моя лямбда должна быть в состоянии прослушать запрос и получить вещи от DynamoDB.
От съемки моего оригинального синего отпечатка выше, вы можете подумать:
Это кажется достаточно легко.
И ты был бы прав, Если Мне когда -либо приходилось иметь дело с одной сущностью проекты
. По мере продолжения проекта, теперь у меня есть вторая организация, чтобы иметь дело с: Статус
(es?) И еще больше скоро появится.
Первоначально я подумал:
1 лямбда на ресурс. /ресурсы
пойдет в Ресурсы-ламбда
и /статус
пойдет в Статус-ламбда
Анкет
Однако этот подход приводит к нескольким вопросам:
- Для каждой конечной точки/лямбда вам необходимо создать 3x ссылки на шлюз API
- Для каждой конечной точки/лямбды вам нужно сделать больше жилья.
- Развертывания будут раздражать, потому что мне нужно было бы обновить конкретную лямбду или несколько лямбдас для реализации одной функции в будущем (то есть, если мне нужно было добавить новое поле в статус
, который использует проекты
)
В конечном итоге я решил:
Нет, мы собираемся попросить API Gateway отправить все (прокси) трафик в один лямбда 1 лямбда, чтобы управлять ими всеми (как прокси -ресурс), а затем Lambda может решить, как с этим справиться.
Вот почему мне нужно было создать маршрутизатор, чтобы моя функция Lambda могла выяснить, что его просят сделать, прежде чем выполнять соответствующий ответ. Например, это должно было бы справиться:
Получить/проекты
— Получите мне все проекты в базе данных.Get/Projects: имя
— Получите мне подробности об одном проекте.Get/status
— Получите мне все записи статуса в базе данных.Get/status/: имя
— Получите мне статус одного проекта в базе данных.
Работая с узлом (и специально выражающим) раньше, я знал, что существует способ указать такие маршруты :
app.get('/users/:userId/books/:bookId', function (req, res) { res.send(req.params) })
И аналогично Lambda, для этого случая, казалось, существовал определенный модуль узлов:
AWS-Lambda-Router
import * as router from 'aws-lambda-router' export const handler = router.handler({ proxyIntegration: { routes: [ { // request-path-pattern with a path variable: path: '/article/:id', method: 'GET', // we can use the path param 'id' in the action call: action: (request, context) => { return "You called me with: " + request.paths.id; } }, { // request-path-pattern with a path variable in Open API style: path: '/section/{id}', method: 'GET', // we can use the path param 'id' in the action call: action: (request, context) => { return "You called me with: " + request.paths.id; } } ] } })
Однако, к сожалению, поддержка прокси -пути все еще остается WIP:( Казалось бы, это подразумевает, что ❌ я не смог бы получить на параметрах маршрута, как имя в Get/Projects/: имя
Womp Womp ❌
Также раздражает, что если вы используете пользовательские узлы-модулы, вам нужно загружать его как ZIP каждый раз (в отличие от возможности кодировать/тестировать в прямом эфире, если вы используете Native/Vanilla Node).
Ну, ЛАБДА, я думаю, что это только вы (-р параметры события) и я на данный момент.
Это просто означало бы, что мне нужно создать свой собственный маршрутизатор, и, к счастью, очевидно? , событие
Полезная нагрузка, которая передается в функцию лямбды с помощью API Gateway Содержит всю информацию, которая нам может понадобиться.
В частности, все вы Действительно Потребность в маршрутизаторе — это три вещи (для начала);
- Метод http:
Получить
,Пост
так далее - Ресурс:
Проекты
- статус
Params (a.k.a Keys):
Как только я извлек эти произведения из Lambda, выполнив следующее:
let method = event.httpMethod let resource = event.path.split("/")[1] let key = event.path.split("/")[2]
Фактическая логика маршрутизатора была не слишком сложной. И я думаю, как в техническом интервью — я придумал 2 «решения».
V1 — включите 1, добавьте больше деталей внутри
let method = event.httpMethod let resource = event.path.split("/")[1] let key = event.path.split("/")[2] switch (resource) { case "projects": if (key == undefined) { body = await dynamo.scan({ TableName: PROJECTS_DB_TABLE }).promise(); } else { let name = key; body = await db_get("projects",name) } break; case "status": break; default: body = { defaultCase: "true", path: event.path, resource: event.path.split("/")[1], }; break; }
Этот подход был крутым, потому что он позволил мне использовать дорожка
в качестве основного селектора, а затем кодируйте логику для необходимых методов по мере их появления.
Однако. Это не … Смотри Отлично. На первый взгляд он выглядит грубым, запутанным, и это просто с одним ресурсом и одним методом. Во -вторых, для любых новых инженеров, приходящих на борту — это не сразу кажется маршрутизатором по сравнению с любой предыдущей работой, которую они могли выполнить.
Возвращаясь к чертежной доске и желая приблизиться к «золотому стандарту», к которому я привык, как в Express-Router.
Я хотел придумать что -то, что просто указало:
- Вот маршрут, с которым нам нужно справиться
- Вот это связанный обработчик.
Имея это в виду, я придумал
V2 — Фильтр на 2 условиях, добавьте больше методов по мере их возникновения
let method = event.httpMethod let resource = event.path.split("/")[1] let key = event.path.split("/")[2] if (method == "GET" && resource == "projects") { body = await db_get(dynamo, "projects", key) } else if (method == "GET" && resource == "status") { body = await db_get(dynamo, "status", key) } else { body = { method, resource, key, message: "not supported at this time" } }
Мне это нравится, потому что это самое близкое, что я смог добраться до экспресс-маркировки:
app.get('/users/:userId/books/:bookId', function (req, res) { res.send(req.params) })
И имеет преимущество в том, чтобы быть кратким и гораздо более узнаваемым в качестве маршрутизатора на первом воздействии.
Вещи, которые я улучшаю
Я, вероятно, хотел бы сделать гораздо большую уборку для настоящего интервью «Real» маршрутизатора, но это было все еще крутое упражнение. Некоторые определенные вещи, которые я бы хотел добавить/обрабатывать:
-
Get-Me-All
Корпус обрабатывается путем проверки неопределенного ключа. Это, вероятно, можно охранять к лучшему. - В настоящее время нет никакой защиты от кого -то, добавляющего более чем параметр 1 -го уровня (то есть
/projects/name/something/else
все равно будет отправлен в DB. Это не здорово. - Это все в гигантском заявлении IF-ELSE ?? Это не кажется великолепным.
- Ограничения: нет способа сделать промежуточное программное обеспечение, аут, трассировку и кучу вещей, которые вы сможете сделать с экспресс-маршрутизатором (и другими маршрутизаторами)
Вывод
Маршрутизаторы-это просто гигантские заявления IF-ELSE? Idk — это было весело, хотя.
Оригинал: «https://dev.to/tratnayake/and-for-this-interview-build-me-a-custom-router-for-a-web-application-30l1»