Автор оригинала: FreeCodeCamp Community Member.
Bruno Krebs.
В этом посте я покажу вам, как вы можете быстро построить Serverless полный стек Приложение со статическим файловым хостингом, безопасный API отдыха и надежный слой настойчивости.
Вот как мы будем управлять всеми движущимися частями:
- Управление идентификацией и безопасность Поддерживается AUTH0 и JSON WEB TOKENS (JWT)
- Serverless Read API предоставляется Экспресс приложение с WebTask.
- Слой настойчивости с База данных Mongodb размещены Mlab.
- Статический файловый хостинг через развертывание в Github Pages.
Поскольку это приложение довольно просто с точки зрения функций, нельзя запустить MongoDB в местной среде. Мы будем использовать MLAB во время разработки, а также в производстве. Единственные инструменты, которые вам нужно установить, являются Nodejs и NPM Отказ
Наше приложение будет иметь следующие функции:
- Войдите и выделите
- Список, который показывает задачи от пользователя
- Форма, которая позволяет пользователям добавлять новые задачи
- Кнопка для каждой задачи, чтобы позволить пользователям удалить эти задачи
Создание нового углового приложения
Мы собираемся создать наше новое угловое приложение с Угловые CLI Отказ На самом деле, мы будем использовать этот инструмент в течение всего процесса, чтобы создать компоненты/услуги и создать наше приложение для производства.
Вот список нескольких команд, которые нам придется выдать, чтобы установить угловую CLI и создать наш скелет приложения:
# install Angular CLI globally npm install -g @angular/cli # create skeleton ng new task-list && cd task-list # serve the skeleton on our dev env ng serve
Последняя команда отвечает за упаковку нашего приложения с профилем разработки, а для обслуживания его локально с помощью Сервер разработки WebPack Отказ После выполнения всех этих команд перейдите к http://localhost: 4200/ Чтобы увидеть это и бегать.
Окрестности угловой с auth0
Первое, что мы собираемся позаботиться о вашем приложении, является безопасность. Безопасность должна быть первым приоритетом в любом приложении, которое обрабатывает чувствительные, третьинные данные, такие как список задач, которые мы собираемся развиваться.
Начать, Подпишитесь на бесплатную учетную запись AUTH0 и обратите внимание на ID клиента и Домен Отказ Оба значения будут использоваться для настройки Замок : Встраиваемая система входа в систему.
Важно : AUTH0 требует списка Допускается URL-адрес обратного вызова Отказ Этот список содержит все URL-адреса, к которым AUTH0 может перенаправлять пользователя после выдачи JWT. Поэтому мы должны настроить не менее двух URL: http://localhost: 4200/ и URL, где наше приложение будет выставлено, что-то вроде: https://brunokrebs.github.io/task-list/ Отказ Этот URL будет определен, когда мы выпустим на страницы GitHub.
Чтобы использовать замок, мы должны установить два библиотека в нашем приложении: auth0-lock и angular2-jwt Отказ Так как мы используем TypeScript с угловым углом, мы также установим @ Типы/auth0-lock Библиотека, которая обеспечивает определения типографии для блокировки. Также, поскольку мы хотим предоставить нашим пользователям хороший интерфейс, мы собираемся установить Угловой материал Отказ Эти зависимости устанавливаются со следующими командами:
# Auth0 Lock and Angular 2 JWT runtime deps npm install --save auth0-lock angular2-jwt @angular/material # Types definitions for Auth0 Lock npm install --save-dev @types/auth0-lock
Давайте будем использовать угловую CLI для создания NavbarComponent Отказ Этот компонент будет иметь Войти и Выйди Кнопки. Мы также создадим AuthService Это будет нести ответственность за Войти , Выйди и подтвердить, если пользователь аутентифицирован или не.
# generates NavBarComponent files under src/app/nav-bar ng g component nav-bar # generates AuthService under src/app/auth.service.ts ng g service auth
После выполнения этих команд угловые CLI создали следующую структуру файла:
src
|-app
|-nav-bar
|-nav-bar.component.ts
|-nav-bar.component.html
|-nav-bar.component.css
|-auth.service.tsЧтобы интегрировать с замком, давайте сначала реализуем SRC/App/auth.service.ts со следующим кодом:
import { Injectable } from '@angular/core';
import Auth0Lock from 'auth0-lock';
import { tokenNotExpired } from 'angular2-jwt';
// FIXME: replace these with your own Auth0 'Client ID' and 'Domain'
const AUTH0_CLIENT_ID = 'YOUR_AUTH0_CLIENT_ID';
const AUTH0_DOMAIN = 'YOUR_AUTH0_DOMAIN';
// this is the key to the JWT in the browser localStorage
const ID_TOKEN = 'id_token';
@Injectable()
export class AuthService {
lock = new Auth0Lock(AUTH0_CLIENT_ID, AUTH0_DOMAIN, {});
constructor() {
// listening to 'authenticated' events
this.lock.on('authenticated', (authResult) => {
localStorage.setItem(ID_TOKEN, authResult.idToken);
});
}
signIn() { this.lock.show(); }
signOut() { localStorage.removeItem(ID_TOKEN); }
authenticated() { return tokenNotExpired(); }
}В указанном выше коде есть три вещи, которые стоит упомянуть. Во-первых, мы должны заменить Auth0_client_id и Auth0_domain со значениями, которые мы отметили ранее. Во-вторых, Id_token Ссылки Ключ был JWT будет сохранен (в браузере пользователя LocalStorage ). И в-третьих, конструктор этой услуги добавляет слушателя обратного вызова в аутентифицирован событие на замке. Этот обратный вызов сохраняет токен, выданный AUTH0 в LocalStorage Отказ Чтобы выйти из пользователя, это просто вопрос удаления этого токена от LocalStorage Отказ
Наше AuthService Класс хорош, но в отличие от Компоненты Угловая CLI не добавляет Услуги нашему @Ngmodule Определение по умолчанию. Чтобы сделать это, откройте SRC/App/app.module.ts Файл, добавьте это Сервис как провайдер и добавить угловой материал в Импорт множество:
// ... other imports
import { AuthService } from './auth.service';
import { MaterialModule } from '@angular/material';
@NgModule({
// ... other properties
imports: [
// ... other imports
MaterialModule.forRoot(),
],
providers: [ AuthService ],
// ... other properties
})
export class AppModule { }Теперь мы можем сосредоточиться на реализации наших NavbarComponent Отказ Во-первых, мы впрыскием AuthService И добавьте три публичных метода, которые будут использоваться нашим интерфейсом HTML. Затем мы реализуем интерфейс и добавим некоторые правила CSS для его улучшения.
Давайте откроем SRC/App/Nav-Bar/Nav-Bar.comPonent.ts Файл и внедрить следующий код:
import { Component } from '@angular/core';
import { AuthService } from '../auth.service';
@Component({
selector: 'app-nav-bar',
templateUrl: './nav-bar.component.html',
styleUrls: ['./nav-bar.component.css']
})
export class NavBarComponent {
constructor(private authService: AuthService) { }
}Этот компонент просто получает AuthService вводится и ничего другого. Введение такого использования услуг позволяет пользователю интерфейсу вызывать его методы, как мы увидим. Теперь, давайте откроем SRC/App/Nav-Bar/Nav-Bar.comPonent.html и реализовать это следующим образом:
Task List
Наше Навкар Раскрывает название нашей приложения вместе с двумя кнопками. В любой момент времени только одна кнопка действительно видна пользователю. Войти Кнопка будет видна, когда пользователь еще не аутентифицирован и Выйди Будет видимым иным образом. Чтобы наш интерфейс выглядеть лучше, мы также добавили span.fill-space элемент. Этот элемент будет отвечать за то, чтобы нажать обе кнопки на правую границу. Для достижения этого нам нужно добавить правило CSS, которое следует за SRC/App/Nav-Bar/Nav-Bar.comPonent.css файл:
.fill-space {
flex: 1 1 auto;
}Хорошо, у нас сейчас есть как NavbarComponent и AuthService полностью реализован и интегрирован. Но нам все еще нужно добавить этот компонент на наш SRC/App/app.component.html Файл, иначе он никогда не получится. Для этого просто замените содержимое этого файла следующей строкой кода:
Если мы запустим наше приложение сейчас, это не будет выглядеть аккуратно, потому что большинство основных браузеров поставляются с 8px маржа на Тело элементы и потому что мы не настроили ни одного Угловой материал тема Отказ Мы исправим обе проблемы, обновляя наши SRC/styles.css файл, как выглядит как:
@import '~@angular/material/core/theming/prebuilt/indigo-pink.css';
body {
margin: 0;
}Теперь у нас приятно идти, поэтому давайте начнем наш сервер развития, выдавая NG служить и отправляйтесь в http://localhost: 4200 посмотреть, как дела. Вы даже можете Войти и выход , хотя нельзя увидеть.
Добавление приветственного сообщения для посетителей
Чтобы сделать наше приложение дружелюбным местом, давайте добавим приветственное сообщение. Для этого сначала мы добавим два метода и впрыскиваем AuthService В SRC/App/app.component.ts Файл, заставляя это выглядеть так:
import { Component } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private authService: AuthService) { }
}После этого мы собираемся добавить сообщение, как MD-карта Компонент из Угловой материал , до SRC/App/app.component.html :
Hello, visitor. Please sign in to manage your task list.
И последнее, мы собираемся исправить интерфейс, добавив правило на src/app/app.component.csss :
.app-container {
padding: 20px;
}Направляясь в наше приложение, http://localhost: 4200/ Мы можем увидеть наше новое приветственное сообщение (если мы не уведились).
Реализация API для отдыха без сервера
Теперь, когда у нас есть наше приложение, интегрированное с помощью AUTH0, что позволяет нашим пользователям войти в систему и выйти, давайте создадим нашу API безвесочных API. Эта API будет работать Пост Запросы (чтобы сохранить новые задачи), Получить запросы (для извлечения задач от пользователя) и Удалить запросы (удалить задачи).
Сначала мы сделаем файл под названием tasks.js В новой папке под названием WebTask , а затем мы добавим следующий код:
'use strict';
// imports node modules
const express = require('express');
const mongojs = require('mongojs');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
// creates Express app with JSON body parser
const app = new express();
app.use(bodyParser.json());
// defines REST API (HTTP methods)
app.get('/', getTasks);
app.post('/', addTask);
app.delete('/', deleteTask);
// exports REST API
module.exports = app;
function addTask(req, res) {
let userCollection = loadUserCollection(req.webtaskContext);
// save new task to user collection
userCollection.save({
createdAt: new Date(),
description: req.body.description
}, () => res.end())
}
function getTasks(req, res) {
let userCollection = loadUserCollection(req.webtaskContext);
// retrieves all tasks sorting by descending creation date
userCollection.find().sort({ createdAt: -1 }, (err, data) => {
res.status(err ? 500 : 200).send(err || data);
});
}
function deleteTask(req, res) {
let userCollection = loadUserCollection(req.webtaskContext);
// removes a task based on its id
userCollection.remove({ _id: mongojs.ObjectId(req.query.id) }, () => res.end());
}
function loadUserCollection(webtaskContext) {
// this secrets are configured when creating the Webtask
const AUTH0_SECRET = webtaskContext.secrets.AUTH0_SECRET;
const MONGO_USER = webtaskContext.secrets.MONGO_USER;
const MONGO_PASSWORD = webtaskContext.secrets.MONGO_PASSWORD;
const MONGO_URL = webtaskContext.secrets.MONGO_URL;
// removes the 'Bearer ' prefix that comes in the authorization header,
let authorizationHeader = webtaskContext.headers.authorization;
authorizationHeader = authorizationHeader.replace('Bearer ', '');
// verifies token authenticity
let token = jwt.verify(authorizationHeader, AUTH0_SECRET);
// connects to MongoDB and returns the user collection
let mongodb = mongojs(`${MONGO_USER}:${MONGO_PASSWORD}@${MONGO_URL}`);
return mongodb.collection(token.sub);
}Кодекс довольно прост и легко понять, но общее объяснение может пригодиться. Основная цель этого файла – экспортировать Экспресс приложение Это обрабатывает три типа HTTP для одного маршрута, главная / маршрут. Эти три метода, как объяснено ранее, позволяют пользователям создавать, получать и удалять задачи из коллекций в базе данных MongoDB.
У каждого пользователя будет собственная коллекция – не лучший подход, поскольку Mongodb может обрабатывать максимум 24 000 коллекций , но достаточно хорошо, чтобы начать. Эта коллекция основана на Sub претензия, который идентифицирует пользователя Присутствует в JWT, выданном AUTH0.
Последнее определение функции в tasks.js Файл, loadusercollection На самом деле несет ответственность за две вещи: соединение безопасности и монгодб. Когда пользователь выдает любой запрос на нашу API, функция проверяет, если Авторизация Отправленный заголовок был фактически подписан AUTH0. Если никто не отправляется, сгенерирована не пользовательская ошибка. Это делается через jwt.veryify Функция с помощью, если AUTH0_SECRET ключ. Вторая ответственность, подключение к MongoDB, обрабатывается Монговс Модуль и зависит от трех переменных конфигурации: Mongo_user , Mongo_password , Mongo_url Отказ
Все эти переменные конфигурации – три для подключения к MongoDB и один для проверки токенов AUTH0 – передаются в WebTask при создании функции без сервеса. Мы посмотрим, как это сделано в ближайшее время.
Это ВСЕ ДЕЯТЕЛЬНОСТЬ API API С помощью этого кода мы готовы обрабатывать запросы пользователей, которые будут отправлены компонентами, которые мы собираемся создавать в нашем угловом приложении. Но есть еще несколько шагов, которые нам нужно выполнить.
Создание базы данных MongoDB
Чтобы нашу жизнь проще и избежать вздыматься на установку и поддержку Mongodb самими собой, мы собираемся использовать MLAB , облачный монгодб. Первое, что нам нужно сделать, это голова на свой сайт и подписаться на бесплатный аккаунт. После проверки нашего адреса электронной почты мы должны Создать новое развертывание Отказ Поскольку мы просто начинаем наше приложение, и мы не получим слишком много трафика, давайте выберем Один узел план и Песочница Тип, который предоставляет нам 500 МБ хранилища БД бесплатно. Вам также нужно будет ввести имя базы данных, выберите что-то вроде Список задач Отказ
Последнее, что нам нужно сделать, это создать пользователь для подключения к этой базе данных. Если вы выберете Список задач Как название вашей базы данных, Это ссылка для создания пользователей Отказ
Настройка учетной записи WebTask
Нам также нужно будет создать WebTask Account , но это так просто, как это может быть. WebTask, являясь продуктом AUTH0, полагается на блокировку и позволяет нам создать учетную запись одним из следующих провайдеров идентификаторов (IDP): Facebook, Github, Google или Microsoft. Это просто вопрос удара кнопки для создания учетной записи.
Выбрав IDP, мы представлены сжатым трехступенчатым процессом, демонстрирующим, как создать Здравствуйте, мир Функция без сердца. У нас уже есть WebTask, чтобы развернуть, поэтому давайте следуем только первые два шага, чтобы настроить инструмент CLI на нашем компьютере:
# install Webtask CLI tool npm install wt-cli -g # initialize it with our email address wt init me@somewhere.com
Вам будет предложено войти в код подтверждения, который был отправлен на ваш адрес электронной почты. Это последний шаг в конфигурации учетной записи WebTask.
Развертывание нашего API для отдыха без сервеса
С помощью учетных записей MLAB и WebTask создаются и наличие инструмента WebTask CLI правильно настроено, мы теперь можем развернуть наш API для отдыха без сервера к производству. Это сделано со следующим кодом:
wt create webtask/tasks.js \ --meta wt-compiler=webtask-tools/express \ -s AUTH0_SECRET=secret-from-auth0.com \ -s MONGO_USER=task-list-user \ -s MONGO_PASSWORD=111222 \ -s MONGO_URL=ds147069.mlab.com:47069/task-list \ --prod
Первый вариант передан на Wt Инструмент указывает, что мы хотим создать WebTask на основе нашего WebTask/Tasks.js файл. Вторым параметром идентифицирует наш код как приложение Express, которое необходимо предварительно скомпилировано WebTask с помощью WebTask-Tools/Express орудие труда. Следующие четыре параметра являются Секреты Что мы используем на нашей WebTask ( -s -s Prefix обозначает их как секреты ). Последний параметр создает нашу WebTask в Производство Режим, который делает его быстрее.
Имейте в виду, что значения выше должны быть заменены значениями, которые поступают с нашей учетной записи AUTH0 и с нашей учетной записи MLAB. AUTH0_SECRET Значение можно найти в том же месте ID клиента и Домен . И последние три значения, связанные с MongoDB, можно найти на панели инструментов MLAB.
Успешно выпустив команду создания WebTask, теперь мы можем сосредоточиться на работе над основной особенностью нашего углового приложения, компонента списка задач.
Создание нашего углового интерфейса
Существует два компонента, которые нам нужно будет создать, чтобы позволить пользователям взаимодействовать с их списками задач. Мы создадим TaskListComponent , чтобы разоблачить список задач и A Cassformcomponent. , это позволит пользователю создавать новые задачи. Помимо этих компонентов, мы создадим TaskListservice Это будет обрабатывать все запросы AJAX. Мы будем использовать угловую CLI, чтобы создать их к нам:
# creates the main component that lists tasks ng g component task-list # creates a component to hold a form to add tasks ng g component task-list/task-form # creates a service to handle all interaction with our REST API ng g service task-list/task-list
Интеграция угловых AND API без сервера
Оба TaskListComponent и CassFormComponent будет зависеть от TasksListservice Чтобы общаться с нашим API Serverless REST API, поэтому сначала давайте обработаем реализацию услуг.
Откройте недавно созданный файл сервиса, SRC/App/Cass-list/Cass-list.service.ts и вставьте следующий код:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { AuthHttp } from 'angular2-jwt';
@Injectable()
export class TaskListService {
private static TASKS_ENDPOINT =
'https://wt-e1870b8a73b27cdee73c468b8c8e3bc4-0.run.webtask.io/tasks';
constructor(private authHttp: AuthHttp) { }
loadTasks$(): Observable {
return this.authHttp.get(TaskListService.TASKS_ENDPOINT);
}
addTask$(task) : Observable {
return this.authHttp.post(TaskListService.TASKS_ENDPOINT,
{ description: task });
}
deleteTask$(task): Observable {
return this.authHttp.delete(TaskListService.TASKS_ENDPOINT +
'?id=' + task._id);
}
} В этом коде есть три важных веща. Во-первых, Tasks_endpoint постоянный. Эта постоянная должна ссылаться на URL возвращено WT создать команда выше.
Во-вторых, этот класс не использует Http . от @ Угловой/http Отказ Используется AuthHTTP , который предоставляется angular2-jwt И что изящно интегрируется с auth0-lock Отказ Экземпляры этого класса автоматически отправляют Авторизация Заголовок с каким-либо содержанием он находит на id_token Ключ в пользовательском браузере LocalStorage Отказ Как вы, возможно, отметили, это то же самое место, где мы хранили токены при настройке AuthService Отказ
В-третьих, все методы в TasksListservice возвращение Наблюдается , Оставляя абонента, чтобы решить, что делать с ответом, отправленным нашим API без серверов без сервезна.
Ввести TaskListservice В наших компонентах нам нужно сделать несколько изменений в нашем главном @Ngmodule , расположен в src/app/app.module.ts :
// ... other imports
import { Http, RequestOptions } from '@angular/http';
import { AuthHttp, AuthConfig } from 'angular2-jwt';
import { TaskListService } from './task-list/task-list.service';
// creates a factory to AuthHttp
export function authHttpFactory(http: Http, options: RequestOptions) {
return new AuthHttp(new AuthConfig(), http, options);
}
@NgModule({
// ... other properties
providers: [
AuthService,
TaskListService, // adds new service
{
provide: AuthHttp,
useFactory: authHttpFactory, // defines how to provide AuthHttp
deps: [ Http, RequestOptions ]
}
],
bootstrap: [AppComponent]
})Первое изменение, которое мы сделали в наш модуль, было добавить TaskListservice Как провайдер, как мы делали раньше с AuthService Отказ Второе изменение также добавлено провайдер, но в более сложной форме.
AuthHTTP Поставщик нужна помощь с завода – объявлена как AuthHttpfactory – быть созданным. Эта фабрика имеет Http . и Запросвертывания В качестве зависимостей, поэтому нам нужно было определить провайдер в качестве буквального объекта, передавая эти зависимости явно.
Листинг задач с угловым
Наше TaskListComponent теперь может быть реализован. Теперь мы откроем SRC/App/Cass-list/Task-list.component.ts Файл и применить код ниже:
import { Component, OnInit } from '@angular/core';
import { TaskListService } from './task-list.service';
@Component({
selector: 'app-task-list',
templateUrl: './task-list.component.html',
styleUrls: [ './task-list.component.css' ]
})
export class TaskListComponent implements OnInit {
private tasks: String[];
constructor(private taskListService: TaskListService) { }
ngOnInit() { this.loadTasks(); }
private loadTasks() {
this.taskListService.loadTasks$().subscribe(
response => this.tasks = response.json(),
error => console.log(error)
);
}
taskAddedHandler(task) {
this.taskListService.addTask$(task).subscribe(
response => this.loadTasks(),
error => console.log()
);
}
deleteTask(task) {
this.taskListService.deleteTask$(task).subscribe(
response => this.loadTasks(),
error => console.log()
);
}
}Этот класс получает TasksListservice вводится и добавить несколько методов обратного вызова к Наблюдается Ответы. Оба talkaddoved $ и DELETETASK $ Триггеры звонка в loadtasks Метод, когда Наблюдается Ответить без ошибок. console.log Запускается этими методами для обработки случаев, когда ошибки выдаются через API Berverless Read.
loadtasks Способ звонков TaskListservice.loadtasks $ назначить результат к Задачи имущество.
С тремя открытыми методами и Задача Свойство заполнено, теперь мы можем реализовать TaskListComponent Интерфейс, который находится в SRC/App/Task-list/Task-list.component.html файл.
Это то, как этот файл должен выглядеть:
Task List All your tasks in one place. {{ task.createdAt | date: 'short' }}
{{ task.description }}
You have no pending tasks.
Здесь мы добавили MD-list Компонент, предоставляется угловым материалом это, что итерации через Задачи , показывая их дату создания и их описание. Кроме того, каждая задача получила кнопка Это позволяет пользователям удалять их.
Чтобы сделать наш интерфейс лучше, давайте добавим два правила CSS к SRC/App/Task-list/Task-list.component.css файл:
.task-item {
padding: 10px;
margin-bottom: 10px;
background-color: #eee;
}
button.delete {
float: right;
top: -60px;
}Это сделает разные задачи, отличаемые с серым цветом фона и нажимайте кнопку Удалить справа, выравнивая его вертикально к задаче.
Теперь наш интерфейс готов к списку задач, поэтому нам нужно сделать его видимым, добавив его в SRC/App/app.component.html файл. Откройте его и TaskListComponent следующее:
Если мы открываем наше приложение в браузере, доступа к http://localhost: 4200 Мы бы увидели следующий экран.
Завершение нашего приложения теперь зависит от реализации последнего компонента, CassFormComponent , чтобы позволить пользователям добавлять задачи в их списки.
Добавление задач с угловым
Чтобы позволить пользователю добавлять задачи, нам нужно открыть SRC/App/Cass-List/Form - Form - Form.comPonent.ts Файл и реализовать это следующим образом:
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-task-form',
templateUrl: './task-form.component.html',
styleUrls: ['./task-form.component.css']
})
export class TaskFormComponent {
@Output()
taskAdded = new EventEmitter();
public task: String = null;
addTask() {
this.taskAdded.emit(this.task);
this.task = null;
}
}Этот компонент принимает ввод задания пользователя и излучает Задавать событие с данными. HTML этого компонента, расположенный в SRC/App/Cass-List/Form - Form - Form.component.html Файл, также действительно просто:
При нажатии, Добавить кнопка триггеры Addtask Метод в компоненте. Этот метод затем триггеры Задавать Эмиттер событий. TaskListComponent это компонент, который будет слушать эти события. Мы уже внедрили метод, называемый Задавать Это может справиться с такими событиями. Нам просто нужно обновить HTML этого компонента, чтобы добавить CassFormComponent и зарегистрируйте обработчик событий.
Сделать это, давайте откроем SRC/App/Task-list/Task-list.component.html и добавьте приложение-задача Тег непосредственно перед нашим списком следующим образом:
И здесь мы идем. Наше приложение теперь полностью реализовано и готово к производству.
Либо это? Если мы немного играем с приложением, мы увидим, что в некоторых условиях пользовательский опыт не так хорош. Приложение занимает некоторое время, чтобы обновить список задач, когда добавлена новая задача, либо существующий удален. Так что есть комната для улучшения.
Добавление индикатора загрузки AJAX
Чтобы решить эту проблему, давайте использовать небольшой модуль под названием Angular 2 Slim Loading Bar Отказ Чтобы установить его запустить NPM Установка --save NG2-Slim-loading-bar а затем откройте SRC/App/app.module.ts Файл для импорта:
// ... other module imports
import { SlimLoadingBarModule } from 'ng2-slim-loading-bar';
@NgModule({
// ... declarations
imports: [
// ... other imports
SlimLoadingBarModule.forRoot()
],
// ... providers and bootstrap
})
export class AppModule { }Мы также импортируем свои правила CSS, добавив следующую строку на нашу SRC/styles.css файл:
@import '~ng2-slim-loading-bar/bundles/style.css'; /* ... everything else ... */
После этого нам нужно сделать наши AppComponent использовать SlimLoadingBarservice Отказ Сделать это, давайте открытым SRC/App/app.component.ts И редактируйте следующим образом:
// ... other imports
import { SlimLoadingBarService } from 'ng2-slim-loading-bar';
// ... component definition
export class AppComponent {
constructor(private authService: AuthService, private slimLoading: SlimLoadingBarService) { }
// ... method definitions
}SlimLoadingBarservice Содержит два метода, которые мы будем использовать: Начать , который запускает панель загрузки; и полный , что заканчивается индикатор погрузки. Эти методы будут зарегистрированы как слушатели событий на TaskListComponent Отказ Мы все еще не создавали излучатели событий в этом компоненте, но мы можем заранее настроить слушателей. Давайте откроем SRC/App/app.component.html и редактировать так:
Последнее, что нам придется сделать, это редактировать SRC/App/Cass-list/Task-list.component.ts файл для создания и использования обоих startajaxrequest и завершиться .ajaxrequest Эмиттеры событий на Tasklistcomponent. :
// ... other imports
import { EventEmitter, Output } from '@angular/core';
// ... component definition
export class TaskListComponent implements OnInit {
@Output()
startAjaxRequest = new EventEmitter();
@Output()
completeAjaxRequest = new EventEmitter();
// ... properties, constructor and ngOnInit definitions
private loadTasks() {
this.startAjaxRequest.emit();
this.taskListService.loadTasks$().subscribe(
response => this.tasks = response.json(),
error => console.log(error),
() => this.completeAjaxRequest.emit()
);
}
taskAddedHandler(task) {
this.startAjaxRequest.emit();
this.taskListService.addTask$(task).subscribe(
response => this.loadTasks(),
error => console.log()
);
}
deleteTask(task) {
this.startAjaxRequest.emit();
this.taskListService.deleteTask$(task).subscribe(
response => this.loadTasks(),
error => console.log()
);
}
} Здесь мы создаем оба излучателя событий и добавили их к трем методам, которые зависят от запроса AJAX. Всякий раз, когда один из этих методов вызывается, мы выделяем событие, через this.startajaxrequest.emit () , чтобы сделать Slim Loading Bar Начните запустить индикатор загрузки бара. После получения ответа от запросов AJAX, отправленные loadtasks Метод, который обновляет список задач, мы говорим Slim Loading Bar завершить свой прогресс через this.completeajaxrequest.emit () Отказ
Если мы запустим наш сервер разработки, выпустив NG служить и идти до http://localhost: 4200/ Мы увидим наше приложение с лучшим пользователем опытом:
Идя жить с страницами GitHub
Наше приложение готово быть развернутым для производства. У нас есть настойчивый слой, который сохраняет все задачи пользователей. У нас есть бессвевенный API отдыха, который принимает Получить , Пост и Удалить просит манипулировать задачами. У нас есть безопасность, предоставляемая AUTH0. И у нас есть хорошая угловая единая страница интерфейс приложения. Единственное, что отсутствует, – это место для размещения наших статических (HTML, CSS и JavaScript) файлов.
Это именно то, что Страницы GitHub предоставляют Отказ Использовать его просто. Нам просто нужно создать хранилище и толкать нашу работу до ветви, называемой GH-Pages Отказ Эта ветвь должна содержать только наши производственные пучки.
Чтобы создать репозиторий GitHUB Перейти к Github , войдите в систему (или зарегистрируйтесь, если у вас нет учетной записи) и выберите Создать новый репозиторий вариант. Создайте свой новый репозиторий, имея его как Список задач Отказ Обратите внимание, что если вы выберете другое имя, вам придется настроить база-href. Параметр NG Build Команда, которую мы будем работать позже.
Теперь мы должны добавить этот репозиторий в качестве пульта в ваше приложение. Когда мы создали наш проект с угловой CLI, он уже пришел с Гит Отказ Мы просто должны добавить этот пульт, совершить все наши изменения и подтолкнуть к своему мастеру:
# adds new repo as a remote git remote add origin git@github.com:YOUR-USERNAME/YOUR-REPO.git # commits our code git add . git commit -m "Task List Angular app with a secure serverless REST API." # push work to new repo git push origin master
Имея наш код в безопасности, теперь мы можем работать над собирается жить задача. Здесь нужны два шага. Первый – подготовить наш код для производства и упаковать его. Опять угловые CLI пригодится. Сделать это, мы просто должны оформить NG Build - prod --base-href =/task-list/ Отказ Обратите внимание, что мы должны установить База-HREF К точному же названию нашего репозитория GitHub, в противном случае наше приложение не сможет загружать все ресурсы, и это не будет работать.
Второй шаг, используемый для обработки угловых CLI, но Эта команда была удалена в последнем выпуске Поэтому нам понадобится третий инструмент для того, чтобы помочь нам здесь. К счастью, есть тот, который очень прост в использовании называется Angular-CLI-GHPAGES Отказ Для установки его выпуска NPM Установить -G angular-CLI-GHPAGES Отказ После этого мы просто должны выполнять Angular-CLI-GHPAGES (Да, без каких-либо параметров) и Voilà. Наше приложение работает и работает на страницах GitHub.
Важно : Не забудьте обновить Допускается URL-адрес обратного вызова На вашей учетной записи AUTH0. Список разрешенных URL-адресов должен иметь URL-адрес, где было открыто наше приложение. Это должно быть что-то вроде https://brunokrebs.github.io/task-list/ Отказ
Заключение
Как мы могли видеть, когда мы выбираем правильные инструменты, это легко добиться великих достижений. Мы ничего не начали, просто идея разработать приложение списка задач и удалось создать и освободить его в Интернет, не так много усилий.
Нам даже не нужно беспокоиться о строительстве, поддерживающих и крепежных серверах для размещения нашего веб-приложения или нашей базы данных. Если бы нам пришлось управлять этими задачами самими собой, мы займем гораздо больше времени и не так уверены в безопасности нашего приложения, неисправности и масштабируемости и масштабируемости.
И это только начало. Свобода от всех этих вопросов позволяет нам сосредоточиться на наших идеях и о том, что делает наши приложения уникальными.
Оригинал: “https://www.freecodecamp.org/news/serverless-rest-api-with-angular-persistence-and-security-ff274f04e3d0/”