portaldacalheta.pt
  • Основен
  • Технология
  • Наука За Данни И Бази Данни
  • Разпределени Екипи
  • Инвеститори И Финансиране
Back-End

Обратният край: Използване на Gatsby.js и Node.js за статични актуализации на сайта



В тази серия статии ще разработим прототип на уебсайт със статично съдържание. Той ще генерира ежедневно актуализирани, прости статични HTML страници за популярни хранилища на GitHub, за да проследява последните им издания. Статичните рамки за генериране на уеб страници имат чудесни функции за постигане на това - ще използваме Gatsby.js, един от най-популярните.

В Gatsby има много начини за събиране на данни за преден край, без да има заден край (без сървър), Безглави CMS платформи и Изходни приставки за Gatsby между тях. Но ние ще приложим back end, за да съхраняваме основна информация за хранилищата на GitHub и техните най-нови версии. По този начин ще имаме пълен контрол както върху нашия заден край, така и върху предния край.



Освен това ще разгледам набор от инструменти за задействане на ежедневна актуализация на вашето приложение. Можете също да го задействате ръчно или когато се случи някакво конкретно събитие.



Нашето приложение отпред ще се изпълнява на Netlify, а приложението отзад ще работи върху Heroku, използвайки безплатен план. Ще спи периодично : „Когато някой осъществи достъп до приложението, мениджърът на dyno автоматично ще събуди уеб dyno, за да стартира типа уеб процес.“ Така че можем да го събудим чрез AWS Ламбда и AWS CloudWatch. Към момента на писането това е най-рентабилният начин да имате прототип онлайн 24/7.



Нашият пример за статичен уебсайт на възел: Какво да очаквате

За да запазя тези статии фокусирани върху една тема, няма да обхващам удостоверяване, валидиране, мащабируемост или други общи теми. Кодиращата част на тази статия ще бъде възможно най-опростена. Структурата на проекта и използването на правилния набор от инструменти са по-важни.

В тази първа част от поредицата ще разработим и внедрим нашето приложение отзад. В втората част , ние ще разработим и внедрим нашето приложение отпред и ще задействаме ежедневни компилации.



Задният край на Node.js

Back-end приложението ще бъде написано в Node.js (не е задължително, но за улеснение) и всички комуникации ще бъдат през REST API. В този проект няма да събираме данни от предния край. (Ако се интересувате от това, погледнете Форми на Гетсби .)

Първо, ще започнем с внедряването на прост заден край на REST API, който разкрива CRUD операциите на колекцията от хранилища в нашата MongoDB. След това ще насрочим cron работа, която използва GitHub API v4 (GraphQL), за да актуализираме документи в тази колекция. След това ще разположим всичко това в облака Heroku. И накрая, ще задействаме възстановяване на предния край в края на нашата cron работа.



език за програмиране c++

Предният край на Gatsby.js

Във втората статия ще се съсредоточим върху изпълнението на createPages ПОЖАР . Ще съберем всички хранилища от задната страна и ще генерираме една начална страница, която съдържа списък на всички хранилища, плюс страница за всеки върнат документ на хранилището. Тогава ще го направим разположим нашия преден край в Netlify .

От AWS Lambda и AWS CloudWatch

Тази част не е задължителна, ако приложението ви не спи. В противен случай трябва да сте сигурни, че задният ви край работи и работи по време на актуализиране на хранилищата. Като решение можете да създадете cron график на AWS CloudWatch 10 минути преди ежедневната си актуализация и да го обвържете като задействащ файл за вашия GET метод в AWS Lambda. Достъпът до back-end приложението ще събуди екземпляра Heroku. Повече подробности ще има в края на втората статия.



Ето архитектурата, която ще приложим:

Архитектурна диаграма, показваща AWS Lambda & CloudWatch, пинг на Node.js back end, който получава ежедневни актуализации чрез консумиране на GitHub API и след това изгражда Gatsby-базирания преден край, който консумира API на back end, за да актуализира статичните си страници и разполага в Netlify. Задният край също се използва за Heroku с безплатен план.



Предположения

Предполагам, че читателите на тази статия имат познания в следните области:

  • HTML
  • CSS
  • JavaScript
  • REST API
  • MongoDB
  • Отивам
  • Node.js

Също така е добре, ако знаете:



  • Express.js
  • Мангуста
  • API на GitHub v4 (GraphQL)
  • Heroku, AWS или друга облачна платформа
  • Реагирайте

Нека да се потопим в изпълнението на задния край. Ще го разделим на две задачи. Първият подготвя крайни точки на REST API и ги обвързва с нашата колекция от хранилища. Второто е внедряване на cron работа, която консумира GitHub API и актуализира колекцията.

Разработване на Node.js Static Site Generator Back End, Стъпка 1: Прост REST API

Ще използваме Express за нашата рамка за уеб приложения и Mongoose за нашата връзка MongoDB. Ако сте запознати с Express и Mongoose, може да преминете към стъпка 2.

(От друга страна, ако имате нужда от повече познания с Express, можете да проверите официалното ръководство за стартиране на Express ; ако не сте на Mongoose, официалното начално ръководство за Mongoose трябва да е полезно.)

Структура на проекта

Йерархията на файла / папката на нашия проект ще бъде проста:

Списък на папките на корен на проекта, показващ папки config, controller, model и node_modules, плюс няколко стандартни root файла като index.js и package.json. Файловете от първите три папки следват конвенцията за именуване на повтаряне на името на папката във всяко име на файл в дадена папка.

В повече детайли:

  • env.config.js е конфигурационният файл на променливите на средата
  • routes.config.js е за картографиране на останалите крайни точки
  • repository.controller.js съдържа методи за работа по нашия модел на хранилище
  • repository.model.js съдържа MongoDB схемата на хранилището и CRUD операциите
  • index.js е клас на инициализатор
  • package.json съдържа зависимости и свойства на проекта

Изпълнение

Изпълнение npm install (или yarn, ако имате инсталирана прежда) след добавяне на тези зависимости към package.json:

{ // ... 'dependencies': { 'body-parser': '1.7.0', 'express': '^4.8.7', 'moment': '^2.17.1', 'moment-timezone': '^0.5.13', 'mongoose': '^5.1.1', 'node-uuid': '^1.4.8', 'sync-request': '^4.0.2' } // ... }

Нашите env.config.js файлът има само port, environment (dev или prod) и mongoDbUri свойства за сега:

module.exports = ;

routes.config.js съдържа картографиране на заявки и ще извика съответния метод на нашия контролер:

const RepositoryController = require('../controller/repository.controller'); exports.routesConfig = function(app) { app.post('/repositories', [ RepositoryController.insert ]); app.get('/repositories', [ RepositoryController.list ]); app.get('/repositories/:id', [ RepositoryController.findById ]); app.patch('/repositories/:id', [ RepositoryController.patchById ]); app.delete('/repositories/:id', [ RepositoryController.deleteById ]); };

repository.controller.js файл е нашият сервизен слой. Неговата отговорност е да извика съответния метод от нашия модел на хранилище:

const RepositoryModel = require('../model/repository.model'); exports.insert = (req, res) => { RepositoryModel.create(req.body) .then((result) => { res.status(201).send({ id: result._id }); }); }; exports.findById = (req, res) => { RepositoryModel.findById(req.params.id) .then((result) => { res.status(200).send(result); }); }; exports.list = (req, res) => { RepositoryModel.list() .then((result) => { res.status(200).send(result); }) }; exports.patchById = (req, res) => { RepositoryModel.patchById(req.params.id, req.body) .then(() => { res.status(204).send({}); }); }; exports.deleteById = (req, res) => { RepositoryModel.deleteById(req.params.id, req.body) .then(() => { res.status(204).send({}); }); };

repository.model.js обработва връзката MongoDb и операциите CRUD за модела на хранилището. Полетата на модела са:

  • owner: Собственик на хранилището (компания или потребител)
  • name: Името на хранилището
  • createdAt: Дата на последното създаване на изданието
  • resourcePath: Последният път на издаване
  • tagName: Последният таг за освобождаване
  • releaseDescription: Бележки по изданието
  • homepageUrl: Началният URL адрес на проекта
  • repositoryDescription: Описание на хранилището
  • avatarUrl: URL адрес на аватара на собственика на проекта
const Mongoose = require('mongoose'); const Config = require('../config/env.config'); const MONGODB_URI = Config.mongoDbUri; Mongoose.connect(MONGODB_URI, { useNewUrlParser: true }); const Schema = Mongoose.Schema; const repositorySchema = new Schema({ owner: String, name: String, createdAt: String, resourcePath: String, tagName: String, releaseDescription: String, homepageUrl: String, repositoryDescription: String, avatarUrl: String }); repositorySchema.virtual('id').get(function() { return this._id.toHexString(); }); // Ensure virtual fields are serialised. repositorySchema.set('toJSON', { virtuals: true }); repositorySchema.findById = function(cb) { return this.model('Repository').find({ id: this.id }, cb); }; const Repository = Mongoose.model('repository', repositorySchema); exports.findById = (id) => { return Repository.findById(id) .then((result) => { if (result) { result = result.toJSON(); delete result._id; delete result.__v; return result; } }); }; exports.create = (repositoryData) => { const repository = new Repository(repositoryData); return repository.save(); }; exports.list = () => { return new Promise((resolve, reject) => { Repository.find() .exec(function(err, users) { if (err) { reject(err); } else { resolve(users); } }) }); }; exports.patchById = (id, repositoryData) => { return new Promise((resolve, reject) => { Repository.findById(id, function(err, repository) { if (err) reject(err); for (let i in repositoryData) { repository[i] = repositoryData[i]; } repository.save(function(err, updatedRepository) { if (err) return reject(err); resolve(updatedRepository); }); }); }) }; exports.deleteById = (id) => { return new Promise((resolve, reject) => { Repository.deleteOne({ _id: id }, (err) => { if (err) { reject(err); } else { resolve(err); } }); }); }; exports.findByOwnerAndName = (owner, name) => { return Repository.find({ owner: owner, name: name }); };

Ето какво имаме след първия си ангажимент: Връзка MongoDB и нашите REST операции .

Можем да стартираме нашето приложение със следната команда:

node index.js

Тестване

За тестване изпратете заявки до localhost:3000 (използвайки например пощальон или cURL):

Поставете хранилище (само задължителни полета)

Публикация: http: // localhost: 3000 / хранилища

Тяло:

Тестването на прототипа на мобилно приложение може да се направи ръчно или какво?
{ 'owner' : 'facebook', 'name' : 'react' }

Вземете хранилища

Вземете: http: // localhost: 3000 / хранилища

Вземете с ID

Вземете: http: // localhost: 3000 / хранилища /:документ за самоличност

Кръпка по ID

Кръпка: http: // localhost: 3000 / хранилища /:документ за самоличност

Тяло:

{ 'owner' : 'facebook', 'name' : 'facebook-android-sdk' }

С тази работа е време да автоматизирате актуализациите.

Разработване на Node.js Static Site Generator Back End, Стъпка 2: Cron Job за актуализиране на изданията на хранилището

В тази част ще конфигурираме проста задача cron (която ще започне в полунощ UTC), за да актуализираме хранилищата GitHub, които вмъкнахме в нашата база данни. Добавихме само owner и name параметри само в нашия пример по-горе, но тези две полета са ни достатъчни за достъп до обща информация за дадено хранилище.

За да актуализираме данните си, трябва да използваме API на GitHub. За тази част е най-добре да сте запознати GraphQL и v4 на API на GitHub .

Ние също трябва създайте GitHub маркер за достъп . Минималният необходим обхват за това е:

Обхватите на GitHub токени, от които се нуждаем, са repo: status, repo_deployment, public_repo, read: org и read: user.

Това ще генерира токен и ние можем да изпращаме заявки до GitHub с него.

Сега да се върнем към нашия код.

Имаме две нови зависимости в package.json:

  • 'axios': '^0.18.0' е HTTP клиент, така че можем да отправяме заявки към GitHub API
  • 'cron': '^1.7.0' е cron планировчик на работа

Както обикновено, изпълнете npm install или yarn след добавяне на зависимости.

Ще ни трябват и две нови свойства в config.js също:

  • 'githubEndpoint': 'https://api.github.com/graphql'
  • 'githubAccessToken': process.env.GITHUB_ACCESS_TOKEN (ще трябва да зададете променливата GITHUB_ACCESS_TOKEN среда с вашия собствен личен маркер за достъп)

Създайте нов файл под controller папка с името cron.controller.js. Той просто ще извика updateResositories метод на repository.controller.js по насрочено време:

const RepositoryController = require('../controller/repository.controller'); const CronJob = require('cron').CronJob; function updateDaily() { RepositoryController.updateRepositories(); } exports.startCronJobs = function () { new CronJob('0 0 * * *', function () {updateDaily()}, null, true, 'UTC'); };

Окончателните промени за тази част ще бъдат в repository.controller.js. За краткост ще го проектираме да актуализира всички хранилища наведнъж. Но ако имате голям брой хранилища, може да надхвърлите ограничения на ресурсите на API на GitHub . Ако случаят е такъв, ще трябва да промените това, за да се изпълнява в ограничени партиди, разпределени във времето.

Изпълнението наведнъж на функционалността за актуализация ще изглежда така:

async function asyncUpdate() { await RepositoryModel.list().then((array) => { const promises = array.map(getLatestRelease); return Promise.all(promises); }); } exports.updateRepositories = async function update() { console.log('GitHub Repositories Update Started'); await asyncUpdate().then(() => { console.log('GitHub Repositories Update Finished'); }); };

Накрая ще извикаме крайната точка и ще актуализираме модела на хранилището.

getLatestRelease функция ще генерира GraphQL заявка и ще извика GitHub API. След това отговорът от тази заявка ще бъде обработен в updateDatabase функция.

async function updateDatabase(responseData, owner, name) { let createdAt = ''; let resourcePath = ''; let tagName = ''; let releaseDescription = ''; let homepageUrl = ''; let repositoryDescription = ''; let avatarUrl = ''; if (responseData.repository.releases) { createdAt = responseData.repository.releases.nodes[0].createdAt; resourcePath = responseData.repository.releases.nodes[0].resourcePath; tagName = responseData.repository.releases.nodes[0].tagName; releaseDescription = responseData.repository.releases.nodes[0].description; homepageUrl = responseData.repository.homepageUrl; repositoryDescription = responseData.repository.description; if (responseData.organization && responseData.organization.avatarUrl) { avatarUrl = responseData.organization.avatarUrl; } else if (responseData.user && responseData.user.avatarUrl) { avatarUrl = responseData.user.avatarUrl; } const repositoryData = { owner: owner, name: name, createdAt: createdAt, resourcePath: resourcePath, tagName: tagName, releaseDescription: releaseDescription, homepageUrl: homepageUrl, repositoryDescription: repositoryDescription, avatarUrl: avatarUrl }; await RepositoryModel.findByOwnerAndName(owner, name) .then((oldGitHubRelease) => { if (!oldGitHubRelease[0]) { RepositoryModel.create(repositoryData); } else { RepositoryModel.patchById(oldGitHubRelease[0].id, repositoryData); } console.log(`Updated latest release: http://github.com${repositoryData.resourcePath}`); }); } } async function getLatestRelease(repository) { const owner = repository.owner; const name = repository.name; console.log(`Getting latest release for: http://github.com/${owner}/${name}`); const query = ` query { organization(login: '${owner}') { avatarUrl } user(login: '${owner}') { avatarUrl } repository(owner: '${owner}', name: '${name}') { homepageUrl description releases(first: 1, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { createdAt resourcePath tagName description } } } }`; const jsonQuery = JSON.stringify({ query }); const headers = { 'User-Agent': 'Release Tracker', 'Authorization': `Bearer ${GITHUB_ACCESS_TOKEN}` }; await Axios.post(GITHUB_API_URL, jsonQuery, { headers: headers }).then((response) => { return updateDatabase(response.data.data, owner, name); }); }

След втория ни ангажимент ще изпълним cron планировчик, за да получавате ежедневни актуализации от нашите хранилища на GitHub .

Почти приключихме със задния край. Но последната стъпка там трябва да бъде направена след внедряването на предния край, така че ще я разгледаме в следващата статия.

Внедряване на Node Static Site Generator Back End в Heroku

В тази стъпка ще разгърнем приложението си в Heroku, така че ще трябва да създадете акаунт с тях ако вече нямате такъв. Ако свържем акаунта си в Heroku с GitHub, ще бъде много по-лесно да имаме непрекъснато внедряване. До този край, Аз съм домакин на моя проект в GitHub .

какво е надолу кръг

След като влезете в акаунта си в Heroku, добавете ново приложение от таблото за управление:

Избор

Дайте му някакво уникално име:

Именуване на приложението ви в Heroku.

Ще бъдете пренасочени към раздел за внедряване. Изберете GitHub като метод за внедряване, потърсете своето хранилище, след което щракнете върху бутона „Свързване“:

Свързване на новия ви репо GitHub с вашето приложение Heroku.

За улеснение можете да активирате автоматичното разполагане. Той ще се разположи всеки път, когато натиснете ангажимент към вашия GitHub репо:

Активиране на автоматично разполагане в Heroku.

Сега трябва да добавим MongoDB като ресурс. Отидете в раздела Ресурси и щракнете върху „Намиране на още добавки“. (Аз лично използвам mLab mongoDB.)

трябва ли да научите c преди c++

Добавяне на ресурс MongoDB към вашето приложение Heroku.

Инсталирайте го и въведете името на приложението си в полето за въвеждане на „Приложение за предоставяне до“:

Страницата за добавяне на mLab MongoDB в Heroku.

И накрая, трябва да създадем файл с име Procfile на основното ниво на нашия проект, който определя командите, които се изпълняват от приложението, когато Heroku го стартира.

Нашите Procfile е толкова просто, колкото това:

web: node index.js

Създайте файла и го ангажирайте. След като натиснете фиксацията, Heroku автоматично ще разгърне приложението ви, което ще бъде достъпно като https://[YOUR_UNIQUE_APP_NAME].herokuapp.com/

За да проверим дали работи, можем да изпратим същите заявки, които изпратихме до localhost.

Node.js, Express, MongoDB, Cron и Heroku: Наполовина сме там!

След третия ни ангажимент, така ще изглежда нашето репо .

Досега внедрихме Node.js / Express-базиран REST API на нашия гръб, актуализаторът, който използва API на GitHub, и cron задача, за да го активира. След това внедрихме нашия заден край, който по-късно ще предостави данни за нашия генератор на статично уеб съдържание използване на Heroku с кука за непрекъсната интеграция. Сега сте готови за втората част , където ние прилагаме предния край и попълваме приложението!

Свързани: Топ 10 на най-често срещаните грешки, които Node.js правят разработчиците

Разбиране на основите

Какво представляват статичните и динамичните уеб страници?

След публикуването статичните уеб страници съдържат едни и същи данни за всички сесии. В динамичните уеб страници данните могат да се актуализират в движение.

Защо Node е популярен?

Node.js е лек, бърз, мащабируем, с отворен код и добре поддържан от своята общност.

Каква е целта на Node.js?

Node.js служи като среда за изпълнение на back-end за изграждане на мащабируеми, леки, асинхронни, управлявани от събития уеб приложения с JavaScript.

Какви са предимствата на Node.js?

Node.js използва същия език (JavaScript) за сървърната страна, който обикновено се използва в браузъра. Той е лек и е проектиран да използва неблокиращи I / O операции, докато заявките се обработват.

Колко важен е Node.js?

Като член на популярния стек MEAN - MongoDB, Express.js, Angular и Node.js - Node.js е важен за разработването на високоефективни, мащабируеми уеб приложения с JavaScript.

Какви са предимствата на GraphQL?

Някои от предимствата на GraphQL включват събиране от сървъра само на това, от което се нуждаете, получаване на множество ресурси в една заявка и факта, че неговите API са самодокументирани.

Защо се използва GraphQL?

GraphQL позволява бързо прототипиране и внедряване на производството. Освен това той използва една крайна точка за всички ресурси, което улеснява комуникацията клиент-сървър.

Каква е целта на Heroku?

Heroku е облачна платформа, фокусирана върху рационализирането на стартирането и мащабирането на приложения.

3D графика: Урок за WebGL

Технология

3D графика: Урок за WebGL
Създаване на разказ от числа

Създаване на разказ от числа

Инвеститори И Финансиране

Популярни Публикации
Разработка на софтуер навсякъде: Моето разпределено отдалечено работно място
Разработка на софтуер навсякъде: Моето разпределено отдалечено работно място
Глава 11 Несъстоятелност: Какво е това и какво се случва след това?
Глава 11 Несъстоятелност: Какво е това и какво се случва след това?
Живейки най-добрия си живот - вдъхновяващата история на успеха на Дейвид Наф
Живейки най-добрия си живот - вдъхновяващата история на успеха на Дейвид Наф
Познайте своя потребител - UX статистика и статистика (с инфографика)
Познайте своя потребител - UX статистика и статистика (с инфографика)
Програмиране със смесени цели числа: Ръководство за вземане на изчислителни решения
Програмиране със смесени цели числа: Ръководство за вземане на изчислителни решения
 
Максималистичен дизайн и проблемът с минимализма
Максималистичен дизайн и проблемът с минимализма
Новата вълна на предприемачеството
Новата вълна на предприемачеството
Внедряване на отдалечен Framebuffer сървър в Java
Внедряване на отдалечен Framebuffer сървър в Java
Емулиране на React и JSX във Vanilla JS
Емулиране на React и JSX във Vanilla JS
Запознайте се с Ecto, безкомпромисна обвивка за бази данни за едновременни приложения на Elixir
Запознайте се с Ecto, безкомпромисна обвивка за бази данни за едновременни приложения на Elixir
Популярни Публикации
  • какво означава материален дизайн
  • защо дизайнерското мислене е важно
  • c ++ <>
  • имате компютър, който в момента работи с Windows 7, което от следните причини би оправдало
  • как да науча програмиране на c++
  • най-добрите писма на главния изпълнителен директор до акционерите
Категории
  • Технология
  • Наука За Данни И Бази Данни
  • Разпределени Екипи
  • Инвеститори И Финансиране
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt