Можно ли на javascript разрабатывать бэкенд

Create a backend in Javascript (part 1): Introduction to Node.js

Here is a series of articles to help you create backend applications in Javascript. Node.js is now a must, so it is essential for a developer to master it. I will publish a new article every two days and little by little you will learn everything there is to know about Node.js To not miss anything follow me on twitter: https://twitter.com/EricTheCoder_

What is Node.js?

NodeJS allows you to run JavaScript code outside of a browser. Node.js is a free, open source, server environment that uses JavaScript language to create server-side web applications. (backend) Node.js works on different platforms (Windows, Linux, Unix, Mac OS X, etc.) With Node.js we can build a fast and highly scalable web application. Using Node.js also means that we can use JavaScript across the stack, i.e. the same language for the frontend and the backend. So more rapid and efficient development. Node.js has a huge library of ready-made packages that will save you a lot of time. These libraries are managed by NPM (Node Package Manager) A special feature of Node.js is that it uses asynchronous programming (running multiple tasks at the same time) vs synchronous programming (running one task at a time) found on many server-side programming languages like PHP and Ruby.

Installing Node.js

Node.js can be installed directly from its website: [https://nodejs.org/en/ marge(https://nodejs.org/en/) Detailed documentation is also available on the Node.js website: [https://nodejs.org/en/docs/ marge(https://nodejs.org/en/docs/) Once the installation is complete, you can check the version installed with this command

Hello World

Tradition requires, the first thing we are going to do is the classic ‘Hello World’ The fastest and easiest way to run code with Node is by using REPL. To launch the REPL, just run this command:

$ node Welcome to Node.js v16.9.1 Type ".help" for more information > 
> console.log('Hello World') Hello World undefined 

The REPL allows you to run javascript but you will understand it is very limited. The REPL is used for running small orders or for testing only. If you want to write a complete program in NodeJS, you will need to create a file and run it. Create and open the app.js file, enter the following line:

Each file is considered by NodeJS to be a module and can therefore be executed. To do this, from the terminal enter: node

There you go, well done you have just created your first NodeJS application! Whenever you need to run NodeJS code you will need to do so with this command. We will see, later that there is a way to create a NodeJS server that will allow code to be executed automatically.

Читайте также:  Synchronized queue in java

JavaScript browser vs JavaScript server

  • A browser application run on the client’s computer
  • A NodeJS application is running on the server
  • With NodeJS, there is no browser so no DOM and no Window object
  • With NodeJS it is possible to access the file system
  • With NodeJS, the module system called ‘CommonJS’ does not work with the same syntax as ES6 JavaScript modules
  • There are objects in NodeJS which are available everywhere in your code. These objects are called the Globals.
    • Here are some of these objects. You will learn how to use it in due course:
      • __dirname (return the path of the current folder)
      • __filename (returns the name of the file being executed)
      • require (allows you to load modules)
      • module (returns info on the current module)
      • process (returns info about the current environment)

      Источник

      Взрослый back-end на node.js возможен?

      В экосистеме Node.js существует довольно много библиотек и фреймворков, которые пользуются определенной популярностью в сообществе. Но ни один из инструментов не решил главную проблему, с которой сталкиваются разработчики, когда пытаются писать бэкенд на Node.js. Это проблема выбора архитектуры.

      Хочу обратить ваше внимание на относительно молодой фреймворк Nest.js. Из коробки он предлагает заранее предопределенную архитектуру, которая заточена под максимально удобную поддержку и масштабируемость вашего приложения. Заложенные архитектурные подходы проверены временем и давно используются в других, более зрелых платформах: Java(Spring), Python(Django), PHP(Laravel) и прочих.

      Авторы Nest.js не скрывают, что их вдохновил один из популярных фреймворков для клиентских приложений — Angular.js, а его авторы ориентировались на походы, используемые в Java и C#. Если вы знакомы с Angular.js, то увидите в Nest.js много схожих идей.

      Основные концепции

      Разберем основные концепции, на которых строится разработка Nest.js-приложений.

      Модули

      Базовым строительным блоком приложения является модуль. Для его определения существует специальный декоратор @Module() . Модуль содержит в себе какую-либо логику, которая удовлетворяет принципу единой ответственности. Например, это может быть модуль авторизации пользователей, модуль работы с товарами или модуль пользовательских рассылок.

      Структура модулей приложения представляется в виде графа, согласно которому любое Nest.js-приложение должно иметь в cвоей основе так называемый корневой модуль. В нем группируются остальные модули. Внутри себя каждый модуль организует работу других строительных блоков приложения: контроллера и провайдеров. Немного позже мы разберем их подробно.

      Ниже приведен пример определения модуля.

      import < Module >from '@nestjs/common'; import < UsersController >from './users.controller'; import < UsersService >from './users.service'; @Module(< controllers: [UsersController], providers: [UsersService], >) export class UsersModule <>

      Контроллеры

      Другой тип строительных блоков — это контроллеры. Они отвечают за обработку входящих запросов и возврат ответа клиенту. Контроллеры определяются с помощью декоратора @Controller() . В качестве аргумента в него передается строка, которая назначает корневой путь для входящих запросов. Так как каждый контроллер принадлежит конкретному модулю, он автоматически будет удовлетворять принципу единой ответственности. То есть каждый контроллер сосредоточен на запросах клиента для одной конкретной функциональности.

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

      import < Controller, Get >from '@nestjs/common'; @Controller('users') export class UsersController < @Get('/:id') getUserById(@Param('id') id: number) < return 'return user by id'; >@Post() create(@Body() dto: CreateUserDto) < return 'new user created'; >>

      Nest.js содержит и другие декораторы запросов, с помощью которых можно реализовать API в стиле CRUD или REST: @Get, @Post, @Put, @Delete .

      Провайдеры (Сервисы)

      Провайдеры предназначены для инкапсуляции логики самого приложения. Это может быть как бизнес-логика, так и инфраструктурная логика. На уровне провайдеров используется один из популярных и привычных нам паттернов — внедрение зависимостей. Таким образом мы можем внедрять провайдеры в контроллеры или другие высокоуровневые провайдеры. Для определения провайдера используется специальный декоратор @Injectable() .

      Также стоит упомянуть, что провайдеры иногда называют сервисами по примеру того, как эти элементы именуются в других фреймворках.

      Давайте рассмотрим пример определения провайдера и встраивания его в контроллер.

      import < Injectable >from '@nestjs/common'; import < InjectModel >from '@nestjs/sequelize'; import < PostModel >from './posts.model'; import < CreatePostDto >from './dto/create-post.dto'; @Injectable() export class PostsProvider < constructor(@InjectModel(PostModel) private postRepo: typeof PostModel) < >async create(dto: CreatePostDto) < return await this.postRepo.create(dto); >async findAll() < return await this.postRepo.findAll(); >async findById(id: number) < return await this.postRepo.findOne(< where: < id >>); > >
      import < Body, Controller, Get, Param, Post >from '@nestjs/common'; import < PostsProvider >from './posts.providers'; import < CreatePostDto >from './dto/create-post.dto'; import < PostModel >from './posts.model'; @Controller('posts') export class PostsController < constructor(private postsProvider: PostsProvider) < >@Post() create(@Body() dto: CreatePostDto) < return this.postsProvider.create(dto); >@Get() getAll() < return this.postsProvider.findAll(); >@Get('/:id') getPostById(@Param('id') id: number) < return this.postsProvider.findById(id); >> 

      Помимо этого в Nest.js существуют другие прикладные строительные элементы: middlewares, pipes, guards, interceptors. Ознакомиться с ними подробнее можно в официальной документации. Здесь мы рассмотрели самые основные.

      Жизненный цикл

      В приложениях, реализованных на Nest.js, любой модуль системы имеет свой жизненный цикл. Это позволяет назначать обработчики событий перехода из одной фазы цикла в другую.

      Стадии жизненного цикла приложения

      • onModuleInit — срабатывает один раз в момент инициализации модуля;
      • onApplicationBootstrap — срабатывает один раз при запуске приложения;
      • onModuleDestroy — срабатывает один раз в момент уничтожения модуля;
      • onApplicationShutdown — срабатывает один раз при завершении работы приложения.

      CLI

      Приятным бонусом является то, что Nest.js имеет в своем наборе удобный cli-интерфейс. Для изучения поддерживаемых команд можно воспользоваться командой для вывода справки.

      Или если вам нужна справка по какой-то конкретной команде:

      С помощью cli можно развернуть структуру нового проекта, сгенерировать полный набор строительных элементов (контроллеры, модули, провайдеры и пр.) и модульные тесты к ним, а также управлять запуском приложения в различных режимах.

      Работа с БД

      Описание работы с базами данных требует отдельной статьи. Но здесь я хотел бы рассказать, что у Nest.js есть полноценная интеграция с SQL и NoSQL-базами. Предлагается на выбор несколько ORM. Наиболее популярные из них это Sequelize ( @nestjs/sequelize ) и TypeORM ( @nestjs/typeorm ). Для работы с MongoDB используется классический драйвер Mongoose ( @nestjs/mongoose ).

      Давайте рассмотрим пару примеров работы с TypeORM. Фрагмент кода, описывающий подключение к БД:

      import < Module >from '@nestjs/common'; import < TypeOrmModule >from '@nestjs/typeorm'; @Module(< imports: [ TypeOrmModule.forRoot(< dialect: 'postgres', host: 'localhost', port: 5432, username: 'root', password: 'root', database: 'test', entities: [], synchronize: true, >), ], >) export class AppModule <>

      И пример определения сущности:

      import < Entity, Column, PrimaryGeneratedColumn >from 'typeorm'; @Entity() export class User < @PrimaryGeneratedColumn() id: number; @Column() firstName: string; @Column() lastName: string; @Column(< default: true >) isActive: boolean; >

      Тестирование

      В плане тестирования у Nest.js тоже всё хорошо:

      • Можно автоматически генерировать кодовую структуру модульных тестов для компонентов системы и e2e-тестов для самого приложения.
      • Из коробки есть дефолтный test-runner, который может запускать тесты изолированно для каждого модуля.
      • Также имеется полноценная интеграция с популярным фреймворком для тестирования — Jest.
      • Используемый подход внедрения зависимостей позволяет легко мокировать компоненты системы при их запуске в тестовом окружении.

      Пример простого модульного теста:

      import < CatsController >from './cats.controller'; import < CatsService >from './cats.service'; describe('CatsController', () => < let catsController: CatsController; let catsService: CatsService; beforeEach(() =>< catsService = new CatsService(); catsController = new CatsController(catsService); >); describe('findAll', () => < it('should return an array of cats', async () => < const result = ['test']; jest.spyOn(catsService, 'findAll').mockImplementation(() =>result); expect(await catsController.findAll()).toBe(result); >); >); >);
      import * as request from 'supertest'; import < Test >from '@nestjs/testing'; import < CatsModule >from '../../src/cats/cats.module'; import < CatsService >from '../../src/cats/cats.service'; import < INestApplication >from '@nestjs/common'; describe('Cats', () => < let app: INestApplication; let catsService = < findAll: () =>['test'] >; beforeAll(async () => < const moduleRef = await Test.createTestingModule(< imports: [CatsModule], >) .overrideProvider(CatsService) .useValue(catsService) .compile(); app = moduleRef.createNestApplication(); await app.init(); >); it(`/GET cats`, () => < return request(app.getHttpServer()) .get('/cats') .expect(200) .expect(< data: catsService.findAll(), >); >); afterAll(async () => < await app.close(); >); >);

      Преимущества

      Предлагаю подытожить и определить преимущества, ради которых стоит обратить внимание на Nest.js:

      • Архитектура. В основе фреймворка лежат правильные архитектурные подходы, которые позволяют разработчику идти по уже намеченному пути и не допускать ошибок.
      • Проверка типов. Nest.js реализован на базе языка TypeScript. Думаю, что не стоит расписывать, какие возможности открывает этот язык. При этом не запрещено использовать обычный JavaScript.
      • DI. Внедрение зависимостей позволяет держать сервисы изолированными от остальной логики, а их код — более поддерживаемым и читаемым.
      • Тестирование. Из коробки Nest.js предоставляет полностью интегрированную и настроенную среду для написания и запуска модульных и e2e-тестов.

      Заключение

      Я хотел обратить внимание сообщества на Nest.js. По моему мнению, в ближайшем будущем его популярность среди разработчиков будет расти. Инструмент привносит системность в подходы к разработке сервисов на Node.js. И благодаря тому, что он первый двинулся в сторону решения архитектурных проблем, мы можем ожидать, что через пару лет он будет занимать весомую долю этой ниши.

      Источник

Оцените статью