Låt oss Bygga en JAMstack E-Handel Butik med Netlify Funktioner

0
11

Många människor är förvirrade om vad JAMstack är. Förkortningen står för JavaScript-Api: er och Markeringar, men verkligen, JAMstack inte inkludera alla tre. Vad som definierar JAMstack är att det serveras utan webbservrar. Om du anser att historien om design, denna typ av abstraktion är inte onaturligt, utan det är den oundvikliga utvecklingen av denna industri har varit på väg mot.

Så, om JAMstack tenderar att vara statisk per definition, det kan inte ha dynamisk funktionalitet, server-side events, eller använda ett JavaScript-ramverk, eller hur? Tack och lov inte så. I denna handledning kommer vi att ställa upp en JAMstack e-handel appen och lägga till några serverlösa funktionalitet med Netlify Funktioner (som abstrakt AWS Lambda, och är super knark i min mening).

Jag ska visa mer direkt hur Nuxt/Vue del var att ställa upp i en uppföljning inlägg, men nu kommer vi att fokusera på Stripen serverlösa funktion. Jag kommer att visa dig hur jag satt här, och vi kommer även prata om hur du ansluter till andra statisk webbplats generatorer som Gatsby.

Denna webbplats och reporäntan bör komma igång om du vill ställa in något som detta upp dig själv:

Demo Webbplats

GitHub Repo

Ställningen vår app

Det allra första steget är att sätta upp vår app. Detta är byggd med Nuxt att skapa en Vue app, men du kan ersätta dessa kommandon med ditt tech stack val:

garn skapa nuxt-app

navet skapa

git add-En
git commit-m “första commit”

git push-u ursprung master

Jag använder garn, hub (som tillåter mig att skapa repor från kommandoraden) och Nuxt. Du kan behöva installera dessa verktyg för lokalt eller globalt innan du fortsätter.

Med dessa kommandon, följ anvisningarna, kan vi sätta upp en helt ny Nuxt projektet, samt reporänta.

Om vi loggar in Netlify och styrka, kommer det att be oss att plocka en reporäntan:

Jag ska använda för garn generera för att skapa projektet. Jag kan lägga till i området inställningar för Nuxt i dist-katalogen och träffa feploy! Det är all tid det tar att sätta upp CI/CD och distribuera webbplats! Nu varje gång jag trycker till master-branch, inte bara kommer jag ut, men jag kommer att få en unik länk för att just använda sig av så väl. Så häftigt.

En grundläggande serverlösa funktion med Netlify

Så här är den spännande delen, eftersom inställningar för denna typ av funktionalitet är så snabb! Om du är obekant med Serverlösa, du kan se det som att samma JavaScript-funktioner som du känner och älskar, men exekveras på servern. Serverlösa funktioner är event-driven logik och deras prissättning är extremt låga (inte bara på Netlify, men branschen) och skalor med din användning. Och ja, vi måste lägga till kvalet här: serverlösa fortfarande använder sig av servrar, men barnvaktsservice dem är inte längre ditt jobb. Låt oss komma igång.

Vår mycket grundläggande funktionen ser ut så här. Jag sparade mitt i en mapp som heter funktioner, och bara kallas det index.js. Du kan verkligen kalla mappen och funktion vad du vill.

// functions/index.js
exporten.handler = asynkron (händelse, sammanhang) => {
return {
statusCode: 200,
kropp: JSON.stringify({
meddelande: “Hej det Tacos”,
händelse
})
}
}

Vi behöver också skapa en netlify.toml-fil i roten av projektet och låta det vet vilken katalog för att hitta den funktion, som i detta fall, är “funktioner.”

// netlify.toml
[bygger]
funktioner = “funktioner”

Om vi driva att behärska och gå in på instrumentpanelen kan du se det som att plocka upp den funktion!

Om du tittar på den slutpunkt som anges ovan den förvaras här:
https://ecommerce-netlify.netlify.com/.netlify/functions/index

Verkligen, för varje webbplats du ger det, URL kommer att följa detta mönster:
https:/<yoursiteurlhere>/.netlify/funktioner/<functionname>

När vi träffar som slutpunkt, det ger oss budskap som vi passerade, liksom alla fall data vi loggat också:

Jag älskar hur några steg som är! Denna lilla bit av kod som ger oss oändliga makt och resurser för rika, dynamisk funktionalitet på våra webbplatser.

Koppla upp Rand

Ihopkoppling med Rand är mycket roligt eftersom det är lätt att använda, sofistikerad, har stora dokument, och fungerar bra med serverlösa funktioner. Jag har andra tutorials där jag använt Rand eftersom jag tycker om att använda deras tjänst så mycket.

Här är ett fågelperspektiv av den app vi kommer att bygga:

Först ska vi gå till Rand instrumentpanelen och få våra nycklar. För någon helt skandaliserad just nu, det är OK, det är provning av nycklar. Du kan använda dem också, men du får lära dig mer om du ställer upp dem på din egen. (Det är två klick och jag lovar det är inte svårt att följa med här.)

Vi kommer att installera ett paket som heter dotenv som kommer att hjälpa oss samla våra nyckel och testa den lokalt. Då kommer vi att förvara våra Rand hemliga nyckeln till en Stripe-variabel. (Du kan kalla det vad som helst, men här har jag kallade det STRIPE_SECRET_KEY, och det är ganska mycket standard för industrin.)

garn lägg till dotenv
kräver(“dotenv”).config()

const rand = require(“rand”)(process.env.STRIPE_SECRET_KEY)

I Netlify instrumentpanelen, vi ska gå för att “Bygga & distribuera,” sedan “Miljö” för att lägga till i miljövariabler, där STRIPE_SECRET_KEY är nyckeln, och värdet kommer att vara nyckeln som börjar med sk.

Vi kommer även att lägga till i några rubriker så att vi inte kör in i CORS frågor. Vi kommer att använda dessa rubriker i hela den funktion vi ska bygga.

const rubriker = {
“Access-Control-Tillåta-Ursprung”: “*”,
“Access-Control-Tillåta-Header”: “Content-Type”
}

Så, nu ska vi skapa funktionalitet för att prata med Rand. Vi ska se till att vi tar hand om det fall att det inte är den HTTP metod som vi förväntar oss, och att vi också är att få den information som vi förväntar oss.

Du kan redan här se, vilka uppgifter vi kommer att behöva för att skicka till rand av vad vi in för. Vi kommer att behöva den token, det sammanlagda beloppet, och en idempotency nyckel.

Om du är obekant med idempotency nycklar, de unika värden som genereras av en klient och skickas till en API tillsammans med en begäran vid anslutningen störs. Om servern tar emot ett samtal inser att det är en kopia, det ignorerar begäran och svarar med en framgångsrik status kod. Åh, och det är ett omöjligt ord att uttala.

exporten.handler = asynkron (händelse, sammanhang) => {
if (!händelsen.kropp || händelse.httpMethod !== “INLÄGG”) {
return {
statusCode: 400,
rubriker
kropp: JSON.stringify({
status: “ogiltig http-metoden”
})
}
}

const data = JSON.parse(händelse.kroppen)

if (!uppgifter.stripeToken || !uppgifter.stripeAmt || !uppgifter.stripeIdempotency) {
konsolen.fel(“information som Krävs saknas.”)

return {
statusCode: 400,
rubriker
kropp: JSON.stringify({
status: “uppgifter saknas”
})
}
}

Nu ska vi på kick off strecket betalning bearbetning! Vi ska skapa en Rand kund som använder e-post och token, göra lite loggning och sedan skapa Rand kostnad. Vi kommer att ange valuta, belopp, e-post, kund-ID, och ge en beskrivning när vi på det. Slutligen, vi kommer att ge idempotency nyckel (uttalas eye-dem-po-tio-se), och log för att det var lyckat.

(Även om det inte visas här, vi kommer också att göra några fel hantering.)

// rand betalning bearbetning börjar här
try {
väntar rand.kunder
.skapa({
e-post: data.stripeEmail,
källa: data.stripeToken
})
.då(kundtjänst => {
konsolen.log(
“från och avgifter, amt: ${data.stripeAmt}, e-post: ${data.stripeEmail}`
)
tillbaka rand.avgifter
.skapa(
{
valuta: “usd”,
belopp: data.stripeAmt,
receipt_email: data.stripeEmail,
kund: kund.id,
description: “Prova-Avgift”
},
{
idempotency_key: data.stripeIdempotency
}
)
.då(resultat => {
konsolen.logga in (“Ladda skapad: ${resultat}`)
})
})

Ansluta den till Nuxt

Om vi ser tillbaka på vår ansökan, som du kan se har vi sidor och komponenter som lever inuti sidor. Den Vuex butik är som att hjärnan i vår ansökan. Det kommer att hålla staten i appen, och det är vad som kommer att kommunicera med Rand. Vi behöver dock fortfarande att kommunicera med våra användare via klienten. Vi kommer att samla in data kreditkort i en komponent som kallas AppCard.vue som kommer att leva på kundvagn sidan.

För det första, vi kommer att installera ett paket som heter vue-stripe-element-plus, som ger oss lite Rand form element som tillåter oss att samla in data kreditkort, och ställer oss upp med ett betal-metod som tillåter oss att skapa polletter för rand betalningshantering. Vi kommer även att lägga till ett bibliotek som heter uuid som kommer att tillåta oss att skapa unika nycklar, som vi ska använda för idempotency nyckel.

garn lägg till vue-stripe-element-plus uuid

Standardkonfigurationen de ger oss möjlighet att arbeta med vue-stripe-element-plus ser ut så här:

<mall>
<div id=’app’>
<h1>Vänligen ge oss din betalningsinformation:</h1>
<kortet class=’stripe-kortet”
:class='{ komplett }’
rand=’pk_test_XXXXXXXXXXXXXXXXXXXXXXXX’
:val=’stripeOptions’
@förändring= ” fullständiga = $event.komplett’
/>
<knappen class=’betala-med-stripe” @klicka= “lön”: handikappinrättningar=’!komplett’>Betala med kreditkort</button>
</div>
</template>
<script>
import { stripeKey, stripeOptions } från”. /stripeConfig.json’
import { Kort, createToken } från ‘vue-stripe-element-plus”

export standard {
data () {
return {
komplett: false,
stripeOptions: {
// se https://stripe.com/docs/stripe.js#element-options för mer information
}
}
},

komponenter: { Kort },

metoder: {
betala () {
// createToken returnerar ett Löfte som beslutar i en följd objekt med
// antingen ett tecken eller ett fel nyckel.
// Se https://stripe.com/docs/api#tokens för det symboliska objektet.
// Se https://stripe.com/docs/api#errors för fel objekt.
// Mer allmänt https://stripe.com/docs/stripe.js#stripe-create-token.
createToken().sedan(data => konsol.log(data.token))
}
}
}
</script>

Så här är vad vi kommer att göra. Vi kommer att uppdatera formuläret för att lagra kundernas e-post och uppdatera betala metod för att skicka och symboliskt eller fel nyckeln till Vuex butik. Vi kommer att sända ut en handling att göra så.

data() {
return {

stripeEmail: “”
};
},
metoder: {
betala() {
createToken().sedan(data => {
const stripeData = { data, stripeEmail: här.stripeEmail };
detta.$lagra.dispatch(“postStripeFunction”, stripeData);
});
},

Att postStripeFunction åtgärder vi expedierat ser ut så här:

// Vuex butik
export const åtgärder = {
async postStripeFunction({ getters, begå }, last) {
begå(“updateCartUI”, “loading”)

try {
väntar axios
.inlägg(
“https://ecommerce-netlify.netlify.com/.netlify/functions/index”,
{
stripeEmail: nyttolast.stripeEmail,
stripeAmt: Matematik.våningen(getter.cartTotal * 100), //den förväntar sig att priset i cent
stripeToken: “tok_visa”, //test token, senare skulle vi använda oss av nyttolast.uppgifter.token
stripeIdempotency: uuidv1() //vi använda detta bibliotek för att skapa ett unikt id
},
{
rubriker: {
“Content-Type”: “application/json”
}
}
)
.då(res => {
om (res.status === 200) {
begå(“updateCartUI”, “framgång”)
setTimeout(() => commit(“clearCart”), 3000)

Vi kommer att uppdatera UI staten för att fylla på medan vi bearbetar. Då använder vi axios att skicka till vår funktion endpoint (den WEBBADRESS som du såg tidigare i inlägget när vi satte upp vår funktion). Vi skickar över e-post, amt, token och den unika nyckel som vi byggt funktionen att förvänta sig.

Sedan om det var lyckat, vi kommer att uppdatera UI staten för att återspegla detta.

En sista anmärkning ska jag ge är att jag lagra UI i en sträng, snarare än en boolean. Jag brukar börja med något som “ledig”, och i det här fallet, ska jag också ha “lastning” “framgång” och “fel.” Jag behöver inte använda booleska stater, eftersom jag har sällan stött på en situation där UI staten bara har två stater. När du arbetar med booleans för detta ändamål, brukar du behöver för att bryta sig in i fler och fler länder, och kontrollera alla av dem kan bli alltmer komplicerad.

Som det står, jag kan återspegla förändringar i ANVÄNDARGRÄNSSNITTET på vagnen sida med lättläst villkorssatser, så här:

<sektion v-if=”cartUIStatus === ‘inaktiv'”>
<app-cart-display />
</section>

<sektion v-else-if=”cartUIStatus === ‘laddar'” class=”loader”>
<app-loader />
</section>

<sektion v-else-if=”cartUIStatus === ‘framgång'” class=”framgång”>
<h2>lycka till!</h2>
<p>Tack för ditt köp. Du kommer att vara att ta emot dina objekt i 4 arbetsdagar.</p>
<p>har Glömt något?</p>

<knappen class=”pay-med-stripe”>
<nuxt-länk exakta=”/”>Tillbaka till Hem</nuxt-länk>
</button>
</section>

<sektion v-else-if=”cartUIStatus === ‘fel'”>
<p>Oj, något gick fel. Som omdirigerar dig till din kundvagn försök igen.</p>
</section>

Och där har du det! Vi är alla ställa upp och köra för att ta emot betalningar med rand på ett Nuxt, Vue webbplats med en Netlify funktion, och det var inte ens så komplicerat att ställa upp!

Gatsby Program

Vi använde Nuxt i detta fall men om du ville ställa upp samma typ av funktionalitet med något som använder Reagera som Gatsby, det finns en plugin för att. (Allt är plugin i Gatsby. ☺️)

Du skulle installera det med detta kommando:

garn lägg till gatsby-plugin-netlify-funktioner

…och lägg till plugin till din ansökan så här:

plugins: [
{
lösa: `gatsby-plugin-netlify-funktioner”,
alternativ: {
functionsSrc: `${__dirname}/src/funktioner”,
functionsOutput: `${__dirname}/funktioner”,
},
},
]

Den funktion som används för serverlösa i denna demo är rakt upp och JavaScript, så det är också bärbara Reagera program. Det finns en plugin för att lägga till Stripe-script till din Gatsby app (igen, allt är en plugin). Rättvis varning: detta lägger till skriptet för varje sida på webbplatsen. För att samla information om kreditkort om kunden, skulle du använda Reagera Rand Element, som är liknande till de Vue är en vi som används ovan.

Se bara till att du samlar in från klient-och passerar all information funktionen förväntar sig:

  • Användaren e-post
  • Det totala beloppet, i cent
  • Token
  • Det viktiga idempotency

Demo Webbplats

GitHub Repo

Med ett så lågt hinder, kan du se hur du kan göra riktigt dynamisk erfarenheter med JAMstack program. Det är fantastiskt hur mycket man kan åstadkomma utan några kostnader för underhåll av servrar. Rand och Netlify Funktioner gör att inrätta betalningar i en statisk applikation sådan smidig utvecklare upplevelse!