Русский
Русский
English
Статистика
Реклама

Webdevelopment

Перевод Отправка ответа с Коа

04.12.2020 18:08:20 | Автор: admin

Перевод статьи подготовлен в преддверии старта курса Node.js Developer.


Koa - это небольшой фреймворк, позволяющий создавать бэкэнд-приложения, работающие на платформе Node.js.

В этой статье мы рассмотрим, как отправлять различные типы ответов с помощью Koa.

Отправка тела (Body)

Для отправки тела ответа можно установить атрибут тела ctx . Например, мы можем отправить тело ответа следующим образом:

const Koa = require('koa');const app = new Koa();app.use(async (ctx, next) => {    ctx.body = 'foo';});app.listen(3000);

В приведенном выше коде мы устанавливаем свойство ctx.body в 'foo' . Таким образом, это то, что мы получим, когда перейдем по адресу / с помощью нашего браузера или сделаем запрос на него с помощью HTTP-клиента.

Заголовок (Header) отправки ответа

Мы можем отправлять ответы в нашем коде Koa, установив свойство ctx.response.

Для установки заголовка мы можем установить заголовок ответа методом ctx.set.

Например, мы можем использовать его следующим образом:

const app = new Koa();app.use(async (ctx, next) => {  ctx.set('Access-Control-Allow-Origin', '*');  ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');  ctx.set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');  ctx.body = 'hello';});app.listen(3000);

В вышеприведенном коде мы вызываем ctx.set для установки различных заголовков, включая заголовоки: Access-Control-Allow-Origin, Access-Control-Allow-Headers и Access-Control-Allow-Methods.

Как только мы сделаем запрос по адресу / , мы увидим эти заголовки в HTTP клиентах, таких как Chrome или Postman.

Код статуса ответа на отправку

Мы можем посылать коды статуса ответа, установив значение кода статуса в свойство respondbse.status.

Например, это можно сделать следующим образом:

const Koa = require('koa');const app = new Koa();app.use(async (ctx, next) => {  ctx.status = 202;  ctx.body = 'accepted';});app.listen(3000);

В коде выше мы установили значение ctx.status 's равным 202. Таким образом, когда мы сделаем запрос по адресу / , мы получим код состояния 202 из запроса.

Некоторые распространенные коды ответа, которые отправляются, включают в себя:

200 - OK

201 - created - создан

202 - accepted - принято

203 - non-authoritative information- неавторитетная информация

204 - no content- нет содержания

301 - moved permanently - перемещено навсегда

302 - found - найдено

303 - see other - см. прочее

307 - temporary redirect - временная переадресация

308 - permanent redirect - постоянная переадресация

400 - bad request - неверный запрос

401 - unauthorized - не аутентифицированный запрос

403 - forbidden- неавторизованный запрос

404 - not found - не найдено

405 - method not allowed- способ не разрешён

406 - not acceptable- неприемлемо

422 - unprocessable entity - необрабатываемая сущность

500 - internal server error- внутреннего ошибка сервера

501 - not implemented- не реализован

502 - bad gateway- неверный шлюз

504 - gateway timeout- таймаут шлюза

Отправка заголовков (Headers)

Мы можем установить свойство ctx.response.lastModified на нужную нам дату.

Например, мы можем установить его следующим образом:

const Koa = require('koa');const app = new Koa();app.use(async (ctx, next) => {  ctx.response.lastModified = new Date(2020, 0, 1);  ctx.body = 'foo';});app.listen(3000);

В приведенном выше коде мы устанавливаем свойство lastModified на 1 января 2020 года, поэтому, когда мы сделаем запрос по адресу /, мы получим Last-Modified из ответа со значением Wed, 01 января 2020 года 00:00:00 GMT .

Мы можем установить заголовок Content-Type, задав свойство ctx.type. Например, это можно сделать следующим образом:

const Koa = require('koa');const app = new Koa();app.use(async (ctx, next) => {  ctx.type = 'text/plain; charset=utf-8';  ctx.body = 'foo';});app.listen(3000);

В приведенном выше коде мы имеем следующую строчку:

ctx.type = 'text/plain; charset=utf-8';

Чтобы установить заголовок Content-Type в 'text/plain; charset=utf-8' . Затем мы увидим это в качестве значения заголовка Content-Type при выполнении запроса по адресу / .

Чтобы добавить еще один заголовок к ответу, мы можем вызвать метод ctx.append() для добавления новых заголовков. Он принимает ключ и значение в качестве своих 2 аргументов.

Например, мы можем использовать его следующим образом:

const Koa = require('koa');const app = new Koa();app.use(async (ctx, next) => {  ctx.append('a', 1);  ctx.body = 'foo';});app.listen(3000);

В приведенном выше коде мы вызвали метод ctx.append() с ключом заголовка 'a' и соответствующим ему значением 1.

Затем, когда мы сделаем запрос по адресу /, то получим заголовок ответа A со значением 1.

Заключение

Мы можем установить заголовки ответов, вызвав метод ctx.append(). Чтобы вернуть тело ответа, мы можем установить свойство ctx.body со значением.

Для установки кода статуса ответа, мы устанавливаем свойство ctx.status.


Записаться на бесплатный урок.

Подробнее..

Перевод Как я реализовал MVC в JavaScript

08.01.2021 02:22:10 | Автор: admin

для лучшей разделяемости кода

Для будущих студентов курса "Архитектура и шаблоны проектирования" и всех интересующихся подготовили перевод полезного материала.

Также приглашаем посетить
открытый вебинар на тему "Интерпретатор". На нем будут обсуждаться назначение и структура шаблона "Интерпретатор", формы Бекуса-Науэра, лексический, синтаксический и семантический анализы.


Что из себя представляет архитектурный паттерн Model, View, Controller (MVC)?

Источник: документация Rails

Архитектура MVC разделяет ваш код на три (3) уровня: модели (Models), представления (Views) и контроллеры (Controllers), выполняющие различные задачи внутри программы.

Изображение взято из ВикипедииИзображение взято из Википедии

Уровень модели

В Ruby on Rails этот уровень содержит модель предметной области, которая обычно представляет определенный класс объектов (например, Человек, Животное, Книги). Обычно именно здесь обрабатывается бизнес-логика, поскольку модель связана с базой данных, и данные для нее извлекаются из строк соответствующей таблицы.

Уровень представления

Обрабатывает визуальное представление ответов, предоставляемых контроллерами. Поскольку контроллер может возвращать информацию в формате HTML, XML, JSON и т. д.

Уровень контроллера

В Rails этот уровень отвечает за взаимодействие с моделью, манипулирование ее данными и предоставление соответствующих ответов на различные HTTP-запросы.

Как бы паттерн MVC выглядел в JavaScript?

Источник: документация MDN

Поскольку JavaScript обычно не предполагает использования баз данных (хотя и может) или обработки HTTP-запросов (опять же, может), паттерн MVC придется немного подкорректировать, чтобы он соответствовал специфике языка.

Изображение взято с MDNИзображение взято с MDN

Уровень модели

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

Возьмем, к примеру, приложение Classroom, которое отслеживает, какие классы посещает человек. В этом случае уровень модели можно разделить на классы, такие как Classroom, Person и модель на основе массива под названием Subjects.

Базовые классы модели

class Classroom {  constructor(id, subject = 'Homeroom') {    this.id = id;    this.persons = [];    this.subject = subject;  }}

Модель Classroom содержит переменные данных, которые будут содержать информацию по каждому классу. Сюда будут входить список всех людей, которые в настоящее время числятся в этом классе, предмет, связанный с этим классом, и его id.

class Person {  constructor(id, firstN = 'John', lastN = 'Doe') {    this.id = id;    this.firstName = firstN;    this.lastName = lastN;    this.subjects = [];    this.classrooms = [];  }}

Модель Person содержит переменные данных, которые будут содержать информацию о каждом человеке. Сюда будут входить его имя и фамилия, предметы, которые он изучает, и классы, которые он посещает.

const subjects = [  "English",  "Math",  "Computer Science",  "Business",  "Finance",  "Home Economics"];

Модель Subjects будет просто массивом, поскольку для этого примера я не собираюсь разрешать манипулировать моделью дисциплин.

Уровень контроллера

Контроллером будет класс, который транслирует вводимые пользователем данные в изменения данных модели.

Например, в приложении Classroom контроллер получает данные, вводимые пользователем, от элементов представления, таких как ввод текста (text input) или выбор из списка опций (select options), а также нажатия кнопок, которые используются для изменения модели.

import classroomModel from "../models/classroom";class ClassroomController {  constructor() {    this.lastID = 0;    this.classrooms = [];    this.selectedClass = null;  }  selectClassroom(classroomID) {    this.selectedClass = this.classrooms    .filter(c => c.id === parseInt(classroomID, 10))[0];  }  addClassroom(subject) {    this.classrooms.push(      new classroomModel(this.lastID, subject)      );    this.lastID += 1;  }  removeClassroom(classroomID) {    this.classrooms = this.classrooms      .filter(c => c.id !== parseInt(classroomID, 10));  }  setSubject(subject, classroomID) {    const classroom = this.classrooms      .filter(c => c.id === parseInt(classroomID, 10))[0];    classroom.subject = subject;  }  addPerson(person, classroom) {    // const classroom = this.classrooms    // .filter(c => c.id === parseInt(classroomID, 10))[0];    if (!person) return;    classroom.addPerson(person);  }  removePerson(person, classroomID) {    const classroom = this.classrooms    .filter(c => c.id === parseInt(classroomID, 10))[0];    classroom.removePerson(person);  }}

В этом случае ClassroomController можно рассматривать как таблицу (если сравнивать с тем, как работает Rails), и каждая строка в этой таблице будет представлять информацию, связанную с каждым уже созданным объектом класса.

Этот контроллер имеет три собственные переменные: lastID (каждый раз, когда объект класса создается и добавляется к массиву классов, значение этой переменной инкрементируется), classrooms (массив всех созданных объектов класса) и selectedClass.

Уровень представления

Этот уровень обрабатывает визуальное представление данных приложения. Этот уровень содержит классы, которые позволяют пользователю видеть данные и взаимодействовать с ними.

Например, в приложении Classroom представление будет предоставлять элементы DOM (объектной модели документа), такие как кнопки, инпуты и контейнеры (<div/>, <span/ >, <p/> и т. д.) для отображения различных людей и классов, и связанных с ними данных.

import classroomController from "../controllers/classroom";import subjects from "../models/subjects";class ClassroomView {  constructor(appDiv) {    this.classroomController = new classroomController();    this.classroomSectionDiv = document.createElement('div');    this.classroomsDiv = document.createElement('div');    this.addclassBtn = document.createElement('button');    this.selectSubjectInput = document.createElement('select');    this.classroomSectionDiv.classList.add('classroom-section');    this.classroomsDiv.classList.add('classroom-container');    this.selectSubjectInput.innerHTML = subjects.map((option, index) => (      `<option key=${index} value=${option}>${option.toUpperCase()}</option>`    ));    this.addclassBtn.textContent = 'New Class';    this.addclassBtn.addEventListener('click', () => this.addClassroom());    this.classroomSectionDiv.append(      this.classroomsDiv, this.selectSubjectInput,      this.addclassBtn,      );    appDiv.appendChild(this.classroomSectionDiv);  }  updateView() {    const { classroomController, classroomsDiv } = this;    const allClassrooms = classroomController.classrooms.map(      c => {        const removeBtn = document.createElement('button');        const classDiv = document.createElement('div');        classDiv.classList.add('classroom');        if (classroomController.selectedClass === c) {          classDiv.classList.add('selected');        }        classDiv.addEventListener('click', () => this.selectClassroom(classDiv.getAttribute('data-classroom-id')));        classDiv.setAttribute('data-classroom-id', c.id);        removeBtn.addEventListener('click', () => this.removeClassroom(removeBtn.getAttribute('data-classroom-id')));        removeBtn.setAttribute('data-classroom-id', c.id);        removeBtn.classList.add('remove-btn');        removeBtn.textContent= 'remove';        const allPersons = c.persons.map(p => (          `<div class="person-inline">            <span class="fname">${p.firstName}</span>            <span class="lname">${p.lastName}</span>            <span class="${p.occupation}">${p.occupation}</span>          </div>`        ));        classDiv.innerHTML = `<div class="m-b">            <span class="id">${c.id}</span>            <span class="subject">${c.subject}</span></div>            <div class="all-persons">${allPersons.join('')}</div>`;        classDiv.appendChild(removeBtn);        return classDiv;      }    );    classroomsDiv.innerHTML='';    allClassrooms.map(div => classroomsDiv.append(div));  }    selectClassroom(classroomID) {    const { classroomController } = this;    classroomController.selectClassroom(classroomID);     this.updateView();  }  addClassroom() {    const {      classroomController,      selectSubjectInput,    } = this;    const subjectChosen = selectSubjectInput.value;    classroomController.addClassroom(subjectChosen);    this.updateView();  }  removeClassroom(classroomID) {    const { classroomController } = this;    classroomController.removeClassroom(classroomID);    this.updateView();  }  addPerson(person, classroomID) {    const { classroomController } = this;    classroomController.addPerson(person, classroomID);    this.updateView();  }}

Класс ClassroomView содержит переменную, которая связана с ClassroomController, который создается при конструкции. Это позволяет уровню представления общаться с контроллером.

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

Все функции в представлении просто захватывают значения из UI элементов DOM и передают их как переменные функциям контроллера. Функции selectClassroom(), addClassroom() и removeClassroom() добавляются к элементам DOM через функцию updateView() как события через функцию addEventListener().

Доступ ко всем контроллерам и представлениям с помощью одного представления

Теперь, поскольку для этого примера у нас есть два контроллера, ClassroomController и PersonController (можно найти в полном проекте), у нас также было бы два представления, и если бы мы хотели, чтобы эти два представления могли взаимодействовать друг с другом, нам пришлось бы создать единое всеобъемлющее представление. Мы могли бы назвать это представление AppView.

import classroomView from './classroom';import personView from './person';class AppView {  constructor(appDiv) {    this.classroomView = new classroomView(appDiv);    this.personView = new personView(appDiv);    this.addPersonToClassBtn = document.createElement('button');    this.addPersonToClassBtn.textContent = 'Add selected Person to Selected Class';    this.addPersonToClassBtn.addEventListener('click', () => this.addPersonToClass());    appDiv.appendChild(this.addPersonToClassBtn);  }  addPersonToClass() {    const { classroomView, personView } = this;    const { classroomController } = classroomView;    const { personController } = personView;    const selectedClassroom = classroomController.selectedClass;    const selectedPerson = personController.selectedPerson;    classroomView.addPerson(selectedPerson, selectedClassroom);    personView.updateView();  }}

Класс AppView будет иметь собственные переменные, которые будут связываться как с ClassroomView, так и с PersonView. Поскольку он имеет доступ к этим двум представлениям, он также имеет доступ и к их контроллерам.

Кнопка выше создается AppView. Оно получает значения selectedClassroom и selectedPerson из соответствующих контроллеров и при взаимодействии запускает функцию addPerson() в ClassroomView.

Чтобы полностью посмотреть приложение Classroom, переходите в CodeSandBox по этой ссылке.

Некоторые преимущества использования структуры MVC

Источники: Brainvire, c-sharpcorner, StackOverflow, Wikipedia

1. Разделение обязанностей

Весь код, связанный с пользовательским интерфейсом, обрабатывается представлением. Все переменные базовых данных содержатся в модели, а все данные модели изменяются с помощью контроллера.

2. Одновременная разработка

Поскольку модель MVC четко разделяет проект на три (3) уровня, становится намного проще поделить и распределить задачи между несколькими разработчиками.

3. Простота модификации

Можно легко вносить изменения на каждый уровне, не затрагивая остальные уровни.

4. Разработка через тестирование (TDD)

Благодаря четкому разделению обязанностей мы можем тестировать каждый отдельный компонент независимо.


Узнать подробнее о курсе "Архитектура и шаблоны проектирования".

Зарегистрироваться на открытый вебинар на тему "Интерпретатор".

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

Кстати, о "красивой упаковке" онлайн-сертификатов мырассказываем в этой статье.

ЗАБРАТЬ СКИДКУ

Подробнее..

Новый график на Moiva.io с данными от StateOfJS

19.01.2021 14:16:27 | Автор: admin

Автор популярных ежегодных отчетов #StateOfJS и #StateOfCSS Sacha Greif (он же автор VulcanJS и Sidebar) обратился ко мне с идей включить данные отчета на Moiva.io.

Я ответил "Конечно!"

Что такое Moiva.io

Это проект цель которого максимально упростить сравнение жаваскрипт библиотек и показать тренды по ряду метрик.

О чем новый график

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

Откуда данные

У меня уже и ранее была мысль добавить данные отчетов в проект и я намеревался вручную собрать все данные и захардкодить.

На мое счастье Sacha Greif подбросил идею использовать их апи. Выяснилось что у них есть открытое и очень толковое GraphQL api. О большем я и мечтать не мог. Дальнейшее - дело техники.

Заключение

Наиболее нагляден новый график на примере сравнения жаваскрипт фреймворков https://moiva.io/?compare=@angular/core+react+svelte+vue.
Любое мнение, фидбек и идеи очень приветствуются.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru