STATE OF THE JAMSTACK NATION STATE OF THE JAMSTACK NATION
Ethernet
JAMstack
• JavaScript • API • Markup DNS BROWSER CDN
DATABASE LOAD BALANCER CLOUD STORAGE
CACHING SERVICE WEB APP SERVERS
JOB QUEUE
SERVICES JOB SERVERS DNS BROWSER CDN DNS BROWSER CDN
SERVICES JAMstack
A modern architecture — Create fast and secure sites and dynamic apps with JavaScript, APIs, and prerendered Markup,
… served without web servers.
SARAH DRASNER @SARAH_EDO DNS BROWSER CDN
SERVICES
• Nuxt (Vue.js) • Next (React.js) • Gatsby (React.js) • Eleventy (Vanilla JS) • Jekyll (Ruby) • Hugo (Go) • More and more… • Contentful • Forestry • Sanity • Netlify CMS • CraftCMS • Decoupled Wordpress • Decoupled Drupal • More and more… Netlify Function
Stripe
Vuex Store
Layouts
Pages Components Vue Single File Components
@sarah_edo Templates in the pages directory
@sarah_edo
Deployed!
@sarah_edo Netlify Function
Stripe
Vuex Store
Layouts
Pages Components functions/index.js exports.handler = async (event, context) =" { return { statusCode: 200, body: JSON.stringify({ message: "Hi there Tacos", event }) } }
netlify.toml
[build] functions = "functions"
yarn add dotenv
require("dotenv").config() const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY), headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type" } exports.handler = async (event, context) =" { if (!event.body || event.httpMethod !$$ "POST") { return { statusCode: 400, headers, body: JSON.stringify({ status: "invalid http method" }) } }
const data = JSON.parse(event.body)
if (!data.stripeToken || !data.stripeAmt || !data.stripeIdempotency) { console.error("Required information is missing.")
return { statusCode: 400, headers, body: JSON.stringify({ status: "missing information" }) } } // stripe payment processing begins here try { await stripe.customers .create({ email: data.stripeEmail, source: data.stripeToken }) .then(customer =" { console.log( `starting the charges, amt: ${data.stripeAmt}, email: ${data.stripeEmail}` ) return stripe.charges .create( { currency: "usd", amount: data.stripeAmt, receipt_email: data.stripeEmail, customer: customer.id, description: "Sample Charge" }, { idempotency_key: data.stripeIdempotency } ) .then(result =" { console.log(`Charge created: ${result}`) }) }) Netlify Function
Stripe
Vuex Store AppCard.vue Layouts
Pages Components yarn add vue-stripe-elements-plus
Please enter your payment details:
AppCard.vue pay() { createToken().then(data =" { const stripeData = { data, stripeEmail: this.stripeEmail }; this.$store.dispatch("postStripeFunction", stripeData); }); }, Vuex store export const actions = { async postStripeFunction({ getters, commit }, payload) { commit("updateCartUI", "loading")
try { await axios .post( "https://ecommerce-netlify.netlify.com/.netlify/functions/index", { stripeEmail: payload.stripeEmail, stripeAmt: Math.floor(getters.cartTotal * 100), //it expects the price in cents stripeToken: "tok_visa", //testing token, later we would use payload.data.token stripeIdempotency: uuidv1() //we use this library to create a unique id }, { headers: { "Content-Type": "application/json" } } ) .then(res =" { if (res.status =&& 200) { commit("updateCartUI", "success") setTimeout(() =" commit("clearCart"), 3000) … Success!
DEMO github.com/sdras/ecommerce-netlify
REPO ecommerce-netlify.netlify.com
@sarah_edo • Centered around a developer friendly, Git-based workflow
• Designed modularly, consuming other services via APIs
• Prebuilt and optimized before being served
• Globally distributed and resilient to heavy traffic • Better performance
• Reduced operations cost
• Increased security
• Cheaper, easier scaling
• 65% LESS EXPENSIVE • AVERAGE SERVER CONNECTION TIME +57% 6x faster
NETLIFY.COM/CASE-STUDIES/SMASHING/
What are you going to build? Thank you! @saah_edo