Первоначально опубликовано в блоге разработчиков Reloadly
Большая часть веб-разработки полного стека эволюционировала от традиционной архитектуры HTML/CSS/JS к использованию полномасштабных JavaScript-библиотек и фреймворков. Одним из них является Svelte, который наряду с Angular, React и Vue в значительной степени используется как быстро масштабируемый веб-фреймворк. В этой статье мы рассмотрим создание веб-приложения полного стека с использованием Node JS для нашего сервера.
Мы создадим магазин подарочных карт CALL OF DUTY, который использует Reloadly’s GiftCard API для создания доступной подарочной карты и Stripe’s Session API для создания сессии оформления заказа, где мы можем приобрести подарочную карту. Читателю будет легче понять концепции этой статьи, если у вас есть промежуточное понимание JavaScript, NodeJS и Svelte. Во время чтения вы можете обратиться к этим ресурсам:
- Начало работы с Svelte
- Просмотр подарочной карты на Reloadly
- Прием платежа на Stripe
TL:DR: Пример кода на GitHub
Создание приложения Svelte и установка зависимостей
Первый шаг к созданию нашего магазина подарочных карт — это создание приложения Svelte с нуля и установка ряда зависимостей (также называемых пакетами). Вот список зависимостей, которые понадобятся для нашего приложения:
- axios: HTTP-клиент на основе обещаний для выполнения API-запросов.
- dotenv: Модуль для загрузки отдельно хранимых переменных окружения.
- express: Фреймворк для приложений Node JS — он будет широко использоваться в нашем сервере.
- sirv-cli: Легкая программа CLI, используемая для сервера статических сайтов. Она автоматически устанавливается при создании нового приложения Svelte.
- stripe: Обертка для API Stripe.
Примечание: Основным условием для этого руководства является наличие установленного Node на вашей машине. Если вы еще не сделали этого, вы можете сделать это здесь.
Перед установкой зависимостей создайте свое приложение, запустив команду Svelte create-app
в терминале:
# create a new Svelte project named "svelte-store"
npx degit sveltejs/template svelte-store
# navigate into the folder of the newly created project
cd svelte-store
# install all dependencies in your local "node_modules" folder
npm install
# deploy your application on a localhost server
npm run dev
На этом этапе вы должны увидеть начальную веб-страницу в браузере при переходе на localhost:8080
.
Создание сервера Node
Следующим шагом будет создание сервера, который будет обрабатывать запросы к API Reloadly и Stripe для получения данных о подарочных картах и покупках соответственно.
Прежде чем мы продолжим, потратьте несколько минут на регистрацию аккаунта Reloadly и Stripe, чтобы получить токен доступа и секретный ключ соответственно. Ниже приведены ссылки на краткие и понятные руководства, которые покажут вам, как это сделать:
- Регистрация в Reloadly
- Регистрация в Stripe
Как только вы получите маркер доступа и секретный ключ, перейдите в папку проекта в терминале и установите список зависимостей, упомянутый ранее:
npm install axios dotenv express stripe
Далее в корневой папке проекта создайте файл .env
, чтобы защитить ваши конфиденциальные учетные данные (маркер доступа и секретный ключ) от отправки в продакшн вместе с вашим кодом. В этом файле добавьте токен доступа и секретный ключ и присвойте их переменным.
.env
STRIPE_KEY='YOUR_SECRET_KEY_HERE'
RELOADLY_TOKEN='Bearer YOUR_ACCESS_TOKEN_HERE'
Далее создайте файл server.js
в корневой папке вашего проекта. Начните работу вашего сервера с импорта (требования) всех установленных вами зависимостей:
// ./server.js
require('dotenv').config();
const express = require("express");
const app = express();
const axios = require("axios");
const stripe = require("stripe")(process.env.STRIPE_KEY);
const accessToken = process.env.RELOADLY_TOKEN
Давайте начнем с получения данных из API подарочных карт Reloadly — создадим кучу переменных для обработки данных запроса и ответа:
// ./server.js
...
const url = "https://giftcards.reloadly.com/products/120";
const headers = {
Accept: "application/com.reloadly.giftcards-v1+json",
Authorization: accessToken,
};
let giftCardsData;
let giftCardsAmount;
...
Далее определим обработчик маршрута, который позволит пользователям нашего приложения сделать GET-запрос к API Reloadly
// ./server.js
...
app.get("/giftcards", (req, res) => {
axios
.get(url, { headers: headers })
.then((response) => {
giftCardsData = response.data;
giftCardsAmount = giftCardsData.fixedRecipientDenominations[0] * 100
res.send({
success: true,
data: giftCardsData,
});
})
.catch((error) => {
res.send({
success: false,
data: error,
});
});
});
...
В приведенном выше фрагменте кода через Axios делается запрос к API Reloadly, а ответ API присваивается существующей переменной. Обратите внимание на параметр ответа fixedRecipientDenominations
— это цена каждой подарочной карты, она перебирается и умножается на 100, чтобы API Stripe не отображал ее в центах.
После этого создайте второй обработчик маршрута, который позволит нашим пользователям делать POST
запрос к API Stripe при покупке подарочной карты
// ./server.js
...
app.post("/create-checkout-session", async (req, res) => {
const session = await stripe.checkout.sessions.create({
line_items: [
{
price_data: {
currency: giftCardsData.recipientCurrencyCode,
product_data: {
name: giftCardsData.productName,
},
unit_amount: giftCardsAmount,
},
quantity: 1,
},
],
mode: "payment",
success_url: "https://www.reloadly.com/",
cancel_url: "https://twitter.com/fullstackmafia",
});
res.redirect(303, session.url);
});
...
В приведенном выше фрагменте кода выполняется запрос к API Stripe для создания сессии оформления заказа с деталями продукта подарочной карты. После каждого сеанса оплаты мы можем либо перенаправить пользователя на страницу с успешным сообщением (success_url
) или неудачным (cancel_url
). Поскольку это демо, я использовал домашнюю страницу Reloadly в качестве успешного сообщения, а мой аккаунт в Twitter — в качестве неудачного сообщения ?.
Наконец, настройте ваш сервер так, чтобы файлы из папки public
вашего проекта были доступны через HTTP-запросы. Также установите обработчик маршрута GET
в корень вашего приложения и подключите ваше приложение к вашему серверу localhost через функцию Express app.listen()
. Эти действия подробно описаны в приведенном ниже фрагменте кода:
// ./server.js
...
app.use(express.static("public"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "public", "index.html"));
});
app.listen(5000, () => {
console.log("Server is up at port 5000");
});
Вот! Вы установили и настроили свой сервер. Вы можете убедиться, что сервер работает, запустив его в терминале командой, приведенной ниже:
node server.js
Это запустит ваш сервер, и вы увидите подтверждающее сообщение, которое вы указали в функции app.listen():
# Server is up at port 5000
Создание компонента Svelte
После запуска сервера следующим шагом будет создание компонента Svelte, который будет отображать подарочную карту, а также страницу оформления заказа для наших пользователей. В папке /src
вашего приложения откройте файл App.svelte
и удалите существующий шаблон.
Для начала мы определим объект, который будет обрабатывать состояние нашего приложения во время выполнения запроса API — с момента запроса на получение подарочных карт до получения ответа от API Reloadly. Давайте начнем с создания объекта в нашем компоненте:
// ./src/App.svelte
<script>
let buju = {
productName: undefined,
loading: false,
};
...
</script>
Далее мы укажем переменную для обработки данных о подарочных картах, которые мы будем получать от нашего сервера. Мы также создадим асинхронную функцию для обработки состояния загрузки и получения данных подарочной карты с сервера:
// ./src/App.svelte
<script>
...
let results;
async function getGiftCards() {
buju.loading = true;
try {
const returnValue = await fetch("/giftcards");
const response = await returnValue.json();
results = response.data;
buju = {
productName: results.productName,
loading: false,
};
} catch (error) {
console.error(error);
}
}
</script>
Теперь мы определили логику для нашего компонента Svelte, давайте завершим отображение, отобразив наше приветственное сообщение с помощью HTML, обернутого тегом Svelte main
:
// ./src/App.svelte
...
<main>
<div>
<p>GET ALL THE CALL OF DUTY GIFT CARDS <br> YOU WANT HERE!</p>
<button class="search_button" on:click={getGiftCards}>SEARCH</button>
</div>
</main>
Далее мы используем блок Svelte if/else
для отображения ответа, который мы получим от нашего сервера. Здесь мы создадим несколько сценариев для получения данных о подарочной карте:
// ./src/App.svelte
...
<main>
<div>
<p>GET ALL THE CALL OF DUTY GIFT CARDS <br> YOU WANT HERE!</p>
<button class="search_button" on:click={getGiftCards}>SEARCH</button>
</div>
<div>
{#if buju.loading === true}
<p>Loading giftcards...</p>
{:else if buju.productName !== undefined }
<div class="results">
<img class="product_image" src="{results.logoUrls[0]}" alt="gift card images" width="200px"/>
<p class="redeem_instructions">Redeem Instructions: {results.redeemInstruction.verbose}</p>
<p class="price">Price: {results.fixedRecipientDenominations[0]} USD</p>
<form action="/create-checkout-session" method="POST">
<button class="search_button" type="submit">BUY NOW</button>
</form>
</div>
{/if}
</div>
</main>
Теперь мы закончили, осталось последнее — нам нужно изменить способ компиляции и загрузки нашего приложения Svelte, загрузив его с сервера. В файле package.json
вашего приложения измените свойство start
в объекте scripts с sirv public --no-clear
на node server.js
:
// ./ package.json
...
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "node server.js"
}
...
Приобретение подарочной карты
Похоже, мы готовы к работе! Давайте сохраним все наши файлы и в терминале перейдем в папку нашего приложения и выполним команду npm run dev
. Как указано на сервере, среда разработки нашего приложения должна работать на порту 5000
. Давайте запустим приложение и попытаемся совершить покупку подарочной карты:
На видео выше мы видим, как работает наше приложение, когда я купил подарочную карту CALL OF DUTY на основе данных, полученных из API подарочных карт Reloadly, завершил заказ через сессию оформления заказа Stripe и был перенаправлен на домашнюю страницу Reloadly в качестве доказательства того, что мой заказ был успешно завершен. Чтобы подтвердить это, ниже приведен снимок экрана из моего аккаунта Stripe, показывающий покупку:
Идем дальше
Развивая наше текущее приложение, мы можем изучить возможность возврата данных о нескольких подарочных картах через конечную точку Reloadly Get all products
gift card endpoint и их оплаты через различные сессии оформления заказа для каждого соответствующего продукта.
Резюме
Работа с Stripe и Node JS для создания приложений полного стека — это здорово, поскольку позволяет расширить кривую обучения и изучить JavaScript с помощью другого подхода. Хотите взглянуть на код? Вы можете найти его здесь, на GitHub. Если у вас есть предложения или мысли, которыми вы хотите поделиться, я буду в разделе комментариев ниже.