Ответы пользователя по тегу Node.js
  • ???????????????????????????????

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    MongoDB имеет ограничение на размер документа в 16Мб.
    Да и сама идея хранить 10000 строк внутри одного документа попахивает.
    Ответ написан
    Комментировать
  • Корректно ли пишу код NodeJS?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Посмотри knex, joi.

    // Для начала разбиваем код на отдельные обработчики и храним все раздельно
    // например в signup.ts
    import { ERR_USER_EXISTS, ERR_USER_CREATION_FAILED } from './utils/error-codes.ts'
    import { planAction, USER_CREATED } from './event-bus/rabbit.ts'
    import { validateSignUpData } from './validator/signup.ts'
    import { userModel } from './model/user.ts'
    
    // собственно обработчик
    export const signup = async (req, res) => {
        const { body } = req // намного удобнее использовать destructuring
        const { email, password } = body  // и const позволяет контролировать неизменность
    
        try {
    
            validateSignUpData({email, password}) // зависит от бизнес-логики
    
            const isUserExists = await userModel.isUserExists(email)
            if (isUserExists) {
                res.status = 400
                res.json({
                    message: 'User exists',
                    code: ERR_USER_EXISTS // вместо написания сообщений об ошибках
                                          // принято возвращать код ошибки
                                          // это позволяет адаптивную локализацию на фронте
                                          // этот код ошибки отличается от HTTP Status Code 
                                          // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
                                          
                })
                return
            }
    
            // попытаемся создать пользователя
            const userInfo = await userModel.createUser({email, password})
            if (!userInfo) {
                // в зависимости от того, как реализован createUser, он может выбрасывать исключение
                // либо возвращать пустоту
                res.status = 400
                res.json({
                    message: 'User creation failed',
                    code: ERR_USER_CREATION_FAILED
                })
                return
            }
    
            // запланируем отсылку события, обычно этот код должен быть реализован асинхронным
            // и не блокировать основной поток событий
            planAction({
                event: USER_CREATED,
                playload: userInfo
            })
    
            // отправим успешный ответ на фронт
            res.status = 200
            res.json(userInfo)
    
        } catch (e) {
            // любая ошибка, где бы она не возникла, должна быть обработана
            // в целом обычно применяется более сложная система с набором специфичных исключений 
            // и общим обработчиком ошибок
            res.status = 501
            res.json({
                message: e.message,
                code: e.code || 0
            })
        }
    }
    
    
    // далее в app.ts
    // затем мы просто привязываем их
    import { signup } from './signup.ts'
    app.post('signup', signup)
    Ответ написан
    1 комментарий
  • Как исключить создание дубликатов при запросе RabbitMQ?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Проверка на занятость EMail есть, но запросы асинхронно срабатывают, и в итоге проверку проходят.

    Ответ напрашивается сам собой. Проверка должна быть выполнена на уровне создания записи.
    Ответ написан
  • Почему MongoDB затыкается на больших скоростях?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Используйте insertMany() https://stackoverflow.com/questions/16726330/mongo...
    Если Монгу тошнит и она не успевает сохранять, то вы приплыли. Добро пожаловать в мир шардинга.

    По-хорошему, не нужно никаких setInterval(). Распарсили страницу, сохранили, дождались пока она сохранилась, пошли за следующей. Для разбивки между парсингами используйте setTimeout().
    Ответ написан
    2 комментария
  • Как правильно делпоить на AWS?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Переведите ваше приложение под create-react-app.
    Оно автоматом все файлики собирает с хэшами.
    Дальше сделайте дистрибьюцию через CloudFront и после сборки приложения грузите в бакет артефакты сборки (s3 sync). После загрузки вызывайте сброс кэша дистрибьюции CF.
    Чтобы не ломать фронт, полностью пишите код обратно совместимым в пределах нескольких последних деплойментов.
    Продумывайте стратегию развертываний и т.д. Вплоть до форсирования перезагрузки на клиенте по событию с сервера.
    Ответ написан
    Комментировать
  • Как работать с большими данными в MongoDB?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Для правильной работы с данными следует использовать курсоры.

    Вам нужно что-то вроде этого.

    Ошибки нет скорее всего из-за закончившейся памяти.
    Ответ написан
    1 комментарий
  • Как запустить команду?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Ответ написан
    Комментировать
  • Разделение прав доступа, express и react?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Права нужно проверять везде. На backend в первую очередь. Т.е. админские API должны возвращать 401, когда они вызываются с привелегиями обычного пользователя. Вы можете написать для этого соответствующее middleware.

    До вас уже все придумано

    https://developerhandbook.com/passport.js/passport...
    https://reactrouter.com/web/example/auth-workflow
    Ответ написан
    Комментировать
  • Что делать с модулями NPM для Сайта?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    У меня впечатление того, что вы не совсем понимаете, что такое NPM и Node.js.

    Для начала нужно разобраться с понятиями клиента и сервера. Клиент - это браузер, сервер - то, откуда клиент получает ресурсы. Ресурсы - это html, css, js (созданный для выполнения на клиенте).

    Node.js - это реализация движка Javascript (того самого, который в бразуере), но с применением его на стороне сервера.

    Javascript - это просто язык программирования, но код, написанный на нем, может выполняться в разных средах, т.е. на стороне сервера (node) или на стороне клиента (браузер). Этот код очень похож, но имеет некоторые отличия.

    npm - это пакетный менеджер, упрощенно его задача скачивать архив с кодом и распаковывать в node_modules.

    Когда вы запускаете app.js, то вы запускаете процесс Node, который интерпретирует файл app.js и выполняет инструкции написанные в нем. В вашем случае эти инструкции говорят - запусти сервер и начни слушать порт 80, отдай нужный контент по запросу. Т.е. app.js файл написан для того, чтобы быть интерпретирован движком Node, а не движком браузера.
    Когда вы подключаете app.js внутрь страницы, то движок браузера не понимает, что делать с этим файлом, т.к. в нем отсутствует поддержка серверного движка. Поэтому вы и видите ошибку.

    По умолчанию npm пакеты сделаны для работы с Node.js движком. Для того, чтобы их содержимое можно было правильно использовать на стороне клиента, придумали различные ухищрения - сборщики. Их задача адаптировать Node.js код для выполнения на стороне клиента. Попутно они делают еще много чего, например разного рода оптимизации и т.д.
    В вашем случае нужно использовать наиболее популярные сборщики - webpack подойдет для старта.

    npm - отличный инструмент для быстрой установки зависимостей, библиотек и т.д. Но им нужно научиться пользоваться. Есть еще nvm - управление версиями Node.js, тоже надо.

    Дам вам совет - посмотрите https://learn.javascript.ru/screencast/nodejs и разберитесь, что и в каком контексте выполняется. Там же вы найдете пояснения по поводу npm.
    Советую пройти https://ru.hexlet.io/courses/js-setup-environment (это бесплатно).
    И это под конец https://learn.javascript.ru/screencast/webpack

    Не торопитесь, вам необходимы базовые знания, потратьте недельку другую на разбор технологий и не будет возникать глупых вопросов.
    Ответ написан
    Комментировать
  • Почему Mongoose уничтожает пул подключений?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Иван Чернышев, есть подозрение, что вы где-то делаете db.close() раньше, чем завершена операция.

    Это как работает пул https://mongodb.github.io/node-mongodb-native/core...

    После чтения исходников https://github.com/mongodb-js/mongodb-core/blob/ma... можно понять, что пул разрушается, когда заканчиваются сокеты или наступает лимит попыток пересоединений.

    Mongoose достаточно старый, они фиксили там ошибки. Попробуйте его обновить.

    Еще включите отладку в монгусе.
    mongoose.set('debug', true)
    Ответ написан
    1 комментарий
  • Как грамотно спроектировать backend real-time приложения?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Архитектурно правильно иметь 1 соединение для транспорта данных. Это экономит ресурсы.
    Далее вам нужен роутинг сообщений.
    Например: селекты обрабатываются модулем страницы, а сообщения в чате - модулем чата.
    Реализуется все это достаточно тривиально через шину событий.
    Ответ написан
    Комментировать
  • Веб-сервер на Node.js. Как организовать и контролировать сервис для прослушивания вебсокета для каждого активного пользователя?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Если вас волнует статическая типизация, то вам следует обратить внимание на Typescript и ts-node.

    По факту все делается достаточно просто при использовании JWT. Вот вам пример https://github.com/auth0-community/auth0-socketio-jwt

    Это поможет въехать в тему https://learn.javascript.ru/screencast/nodejs#node...
    Ответ написан
    Комментировать
  • Есть ли бесплатный сервер для скрипта Node.Js?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Есть огромное количество недорогих VPS хостингов, можете взять практически любой из них и крутить там.

    У AWS есть бесплатный план на 1 год для новых пользователей. Если вам не требуется постоянное сокетное подключение и не очень много вызовов, то можно использовать Lambda функцию. Это очень дешево, плюс там есть бесплатное количество вызовов на старте.
    Ответ написан
    Комментировать
  • Существует ли аналог "пиэчпишного" PDO для Node.js?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Обычно берут knex вместо PDO. Для Монги берут mongoose.
    Для фильтрации можно поискать какой-нибудь причиндал вроде Swagger. Можно добавить Joi или Hapi для пущей остроты ощущений.
    Ответ написан
    Комментировать
  • Какую архитектуру проекта выбрать?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Для всех пользователей - лендинг на www.example.com.
    Все API www.example.com/api/version/whatever

    Все скрывать за реверсивным прокси!
    full-stack-front-end-back-end-comic-joke


    А теперь почему следует делать именно так.
    Домен следует вешать на www по простой причине - субдомены кэшируются на более короткое время, а следовательно переезд будет менее болезненный.
    Лендинги и дребедень делать удобнее всего внутри каталогов. Например, у вас есть ссылка www.example.com/megapartner она может быть расшарена в соц.сетях, на форумах и т.д. Это все увеличивает вес вашего домена для поисковых систем. Если вы будете использовать субдомены, то этот вес будет размываться, т.к. поисковики будут все считать разными сайтами.
    Авторизация и управление пользователями должны быть унифицированы. Не стоит делать 20 разных мест, для которых надо авторизовываться по 100 раз. Для этого давно были придуманы роли. Я рекомендую сразу реализовывать вход через тот же Facebook/Google/OK/VK и т.д.
    Общая авторизация дает громадное количество преимуществ, например облегчает поддержку в разы, позволяет знать контекст выполнения действий.
    Один домен облегчает взаимодействие с пользователем, т.к. ему не нужно запоминать десяток разных страниц.
    Ну и дополнительные плюшки реверсивного прокси заключаются в том, что всегда можно настроить редирект, что-то закэшировать, показать правильную станичку, если какой-то из сервисов отвалился.
    Позади прокси следует все делить по назначению, держать каждый проект в разных репозитариях и т.д. Это может существенно упростить разработку, например можно отдать какой-то лендинг в переработку просто дав доступ к репозитарию.

    Если очень хочется упороться и поиграть в девопса, разбейте на 100500 микросервисов, засуньте все внутрь кубернетиса с каким-нибудь истио. Будет красивая архитектура с контейнерами и плюшками.
    Когда наиграитесь, возьмете обычный nginx, напишете конфигурацию простого реверса и он будет работать годами как часы.
    Ответ написан
    Комментировать
  • Как искать в aggregate Mongo?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Не следует использовать стадию $match внутри оператора $sum на стадии группировки.

    db.operations.aggregate([
    	{
    		$match: {"address" : "Office 1"}
    	},
    	{
    		$project: {
    			address: "$address",
    			received: {
    				$cond: [ {$eq: ["$operation_type", "receive"]}, "$amount", 0 ]
    			},
    			sent: {
    				$cond: [ {$eq: ["$operation_type", "send"]}, "$amount", 0 ]
    			},
    			dateTime: "$dateTime"
    		} 
    	}, 
    	{
    		$group: {
    			_id: {
    				address: "$address",
    				day: { $dayOfYear: "$dateTime" },
    				year: { $year: "$dateTime" }
    			},
    			received: {
    				$sum: "$received"
    			},
    			sent: {
    				$sum: "$sent"
    			}
    		}
    	}
    ])
    Ответ написан
    Комментировать
  • Как грамотно использовать сторонние API в своем web приложении на NodeJS?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    1. Почему не использовать Google Actions? Или штук вроде dialogflow.com?
    2. Снижение задержек возможно рядом трюков вроде начала отправки голосовых данных непосредственно в сервис с момента начала их произношения. Далее слой кэширования результатов вычленения намерений.
    3. Размещение всего стека распознавания речи и интентов у себя.
    4. Распараллеливание цепочки там, где это возможно.
    Например
    - Купи билеты в кино на хороший фильм Тарантино
    1. Распознавание
    2. Параллельно:
       = Поиск хороших фильмов Тарантино
       = Поиск кинотеатров поблизости
       = Получение данных вашего календаря
    3. = Запрос расписаний из ближайших кинотеатров (можно делать параллельно, если нет общего API)
    4. Поиск оптимального сеанса
    5. Заказ билетов

    5. Асинхронное выполнение через очередь, где возможно.
    Например:
    - Отправь билеты маме.
    - Хорошо. (ставится задание в очередь, выполняется асинхронно не блокируя пользователя)
    Ответ написан
    Комментировать
  • Имеет ли смысл Nginx перед Node.js на AWS?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Смысла не имеет, поскольку контент лучше класть в S3 и раздавать его оттуда через CloudFront.
    То, что делает ваш nginx, прекрасно делается через ELB.
    Самое главное, если использовать средства Cloud Formation достаточно просто масштабировать проект без исправления каких-либо конфигов и т.п.
    Ответ написан
    5 комментариев
  • Как оптимизировать запрос mongodb?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Сделать индивидуальный индекс для тегов
    schema.index( { url: 1 } )
    schema.index( { tags: 1 }, {sparse: true} )
    schema.index( { catalog: 1 } )


    Склеить теги в одно поле, построить по нему индекс.

    RTFM mongoosejs.com/docs/guide.html#indexes

    Сортировка занимает много времени, т.к. используется индекс catalog_1_tags_1 для условия. Разумеется сортировать по нему не получится.
    Попробуйте сортировать так:
    { $sort: { catalog: 1, tags: 1 } },
    Ответ написан