Monetice el software de código abierto con las funciones de Gatsby y Stripe

Publicado: 2022-03-10
Resumen rápido ↬ Las funciones de Gatsby brindan a los desarrolladores front-end una forma de escribir y usar código del lado del servidor sin la molestia de mantener un servidor. Si le interesa ganar dinero con el código abierto y su sitio no está construido con Gatsby, este enfoque bien puede ser la respuesta que estaba buscando.

En este artículo, explicaré cómo he usado Gatsby Functions y la API de Stripe para habilitar contribuciones seguras de "Paga lo que quieras" que ayudan a financiar mi proyecto de código abierto MDX Embed.

Nota : MDX Embed le permite insertar fácilmente contenido multimedia popular de terceros, como videos de YouTube, tweets, publicaciones de Instagram, lecciones de Egghead, Spotify, TikTok y muchos más directamente en su .mdx , sin necesidad de importar.

Funciones sin servidor de Gatsby

Las funciones de Gatsby abren un mundo completamente nuevo para los desarrolladores front-end, ya que brindan una forma de escribir y usar código del lado del servidor sin la molestia de mantener un servidor. Los usos de las funciones sin servidor van desde suscripciones a boletines con ConvertKit, envío de un correo electrónico con SendGrid, almacenamiento de datos en una base de datos como Fauna o, en este caso, aceptación de pagos seguros con Stripe: ¡la lista es francamente interminable!

Los servicios de terceros como los mencionados anteriormente solo aceptarán solicitudes que se envíen del lado del servidor. Hay varias razones para esto, pero el uso de claves seguras o privadas suele ser una de ellas. El uso de estas claves del lado del servidor significa que no están expuestas al cliente (navegador) y no se puede abusar de ellas, y es aquí donde las funciones sin servidor de Gatsby pueden ayudar.

Gatsby proporciona el mismo enfoque lógico para las funciones sin servidor que con las páginas. Por ejemplo, las páginas del sitio web se encuentran en src/pages y las funciones sin servidor se encuentran en src/api .

Naturalmente, hay un poco más que eso, pero la experiencia del desarrollador de Gatsby es lógica y consistente, ¡y por mi parte me encanta eso!

Funciones del mismo origen

Nueve de cada diez veces, cuando trabaje con funciones sin servidor, las usará de la forma en que se suponía que debían usarse, por ejemplo, su sitio web usa sus propias funciones. Llamo a este uso funciones del mismo origen o SOF para abreviar. En este escenario, tanto el front-end como la API se implementan en el mismo origen, por ejemplo, www.my-website.com y www.my-website.com/api, y la comunicación entre los dos es fluida y, por supuesto. , ardiendo rápido!

Aquí hay un diagrama para ayudar a ilustrar cómo se ve:

Diagrama de la misma función de origen
Un sitio web de Gatsby que utiliza sus propias funciones sin servidor. (Vista previa grande)

Funciones de origen cruzado

Hay, sin embargo, al menos dos escenarios que he encontrado donde he necesitado lo que he estado llamando "Funciones de origen cruzado" (o COF para abreviar). Los dos escenarios en los que he necesitado COF son los siguientes:

  1. Necesito capacidades del lado del servidor, pero el sitio web de origen no puede ejecutar funciones sin servidor.
  2. La función sin servidor es utilizada por más de un origen.

Nota : el uso de Gatsby no es la única forma de escribir funciones sin servidor, pero más sobre eso en un momento.

Experimenté por primera vez con este enfoque en noviembre de 2020 antes del lanzamiento de Gatsby Functions y usé Netlify Functions para proporcionar comunicaciones de servidor a servidor con la API de Twitter y mi blog y cartera comercial de Gatsby. Puede leer sobre este enfoque aquí: Use Netlify Functions y Twitter API v2 como un CMS para su blog de Gatsby.

Después del lanzamiento de Gatsby Functions en junio de 2021, refactoricé lo anterior para trabajar con Gatsby Functions y aquí hay un poco más de información sobre cómo lo hice y por qué: Uso de Gatsby Functions como una API abstracta.

Aquí hay un diagrama para ilustrar mejor el enfoque general.

Diagrama de la función de origen cruzado
Dos sitios web que utilizan las funciones sin servidor de una API de Gatsby. (Vista previa grande)

En el diagrama anterior, el website-1.com está construido con Gatsby y podría haber usado funciones sin servidor (pero no lo hace) y el website-2.com está construido usando algo que no tiene capacidades de función sin servidor.

Nota : en ambos casos, ambos deben usar el mismo servicio de terceros, por lo que tiene sentido abstraer esta funcionalidad en una API independiente.

La API independiente de ejemplo ( my-api.com ) también es un sitio de Gatsby y tiene capacidades de función sin servidor, pero lo que es más importante, permite que los sitios web de otros orígenes utilicen sus funciones sin servidor.

Sé lo que estás pensando: ¡CORS! Bueno, siéntate tranquilo. Cubriré esto en breve.

¡Más después del salto! Continúe leyendo a continuación ↓

Monetización de MDX Embed

Esta fue la situación en la que me encontré con MDX Embed. El sitio web de documentación para este proyecto está construido usando Storybook. Storybook no tiene capacidades sin servidor, pero realmente necesitaba comunicación de servidor a servidor. ¿Mi solución? Creé una API independiente llamada Paulie API.

API de Paulie

La API de Paulie (como la API independiente de ejemplo mencionada anteriormente) puede aceptar solicitudes de sitios web de diferentes orígenes y puede conectarse a varios servicios de terceros diferentes, uno de los cuales es Stripe.

Para habilitar los pagos de Stripe desde MDX Embed, creé un punto final api/make-stripe-payment en la API de Paulie que puede pasar la información relevante de MDX Embed a través de su propia función sin servidor y a la API de Stripe para crear un "pago". Puedes ver el código src aquí.

Una vez que se ha creado con éxito un pago, la API de Stripe devuelve una URL. Esta URL se devuelve a MDX Embed, que abre una nueva ventana en el navegador donde los "clientes" pueden ingresar de manera segura sus detalles de pago en una página web de Stripe... ¡y boom! ¡A usted le pagan!

Aquí hay un diagrama que ilustra mejor cómo funciona esto:

Diagrama de MDX Embed usando Paulie API
MDX Embed se conecta a la API de Stripe a través de las funciones sin servidor de la API de Paulie. (Vista previa grande)

Este enfoque es el mismo que se mencionó anteriormente, donde https://mdx-embed.com envía solicitudes a https://paulieapi.gatsbyjs.io, que a su vez se conecta a la API de Stripe mediante la comunicación de servidor a servidor. Pero antes de continuar, vale la pena explicar por qué no usé react-stripe-js .

react-stripe-js

react-stripe-js es un kit de herramientas del lado del cliente (navegador) que le permite crear pagos y elementos de Stripe en su proyecto React. Con react-stripe-js puedes configurar un método para aceptar pagos de forma segura sin necesidad de comunicación del lado del servidor, pero… y hay un pero. Quería implementar las contribuciones de "Paga lo que quieras". Permítanme explicar.

Esta es una captura de pantalla del "producto" MDX Embed que configuré en mi tablero de Stripe. Note que el precio es $1.00.

Captura de pantalla del tablero de Stripe con un precio de $1.00 para el producto MDX Embed
Sección de productos del tablero de instrumentos. (Vista previa grande)

Si hubiera usado react-stripe-js para habilitar los pagos, se les pediría a todos los "clientes" que pagaran la misma cantidad. En este caso, es solo $ 1.00 y eso no va a pagar las cuentas, ¿verdad?

Para habilitar "Pague lo que quiera" (por ejemplo, una cantidad nominal elegida por un "cliente"), debe profundizar un poco más y usar la comunicación de servidor a servidor y enviar esta cantidad a la API de Stripe usando una solicitud HTTP personalizada. Aquí es donde estoy usando una función Gatsby y paso un valor dinámico que luego se usará para crear la experiencia de "pago" y sobrescribir el precio definido en mi tablero de Stripe.

En MDX Embed, agregué un HTML <input type="number" /> que permite a los "clientes" establecer una cantidad en lugar de pagar una cantidad predefinida, ¡si todo el comercio electrónico fuera así!

Aquí hay un pequeño video que hice que muestra cómo MDX Embed, Paulie API y Stripe API funcionan juntos:

Cómo MDX Embed, la API de Paulie y la API de Stripe funcionan juntas para habilitar "Pague lo que quiera".

Al pasar el valor de entrada de MDX Embed a la API de Paulie, que a su vez se conecta a la API de Stripe, puedo crear un pago "dinámico".

Nota : Esto ahora significa que los "clientes" pueden decidir cuánto vale el proyecto para ellos y establecer una cantidad adecuada para contribuir.

Me gustaría mencionar a Benedicte Raae en este punto, quien me mostró este enfoque por primera vez durante su fabuloso curso de funciones de verano . Puede obtener más información visitando Códigos de Queen Raae. ( ¡Gracias Benedicte, eres el mejor! )

Hablemos de CORS

De forma predeterminada, CORS no bloqueará las funciones sin servidor de Gatsby, ya que el front-end y la API se implementan en el mismo origen. Sin embargo, al desarrollar funciones de origen cruzado, deberá configurar su API para que acepte solicitudes de orígenes diferentes al suyo.

Aquí hay un fragmento de código para mostrar cómo manejo CORS en el punto final api/make-stripe-payment :

 // src/api/make-stripe-payment const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY) import Cors from 'cors' const allowedOrigins = [ 'https://www.mdx-embed.com', 'https://paulie.dev', ] const cors = Cors({ origin: (origin, callback) => { if (allowedOrigins.includes(origin)) { callback(null, true) } else { callback(new Error()) } }, }) const runCorsMiddleware = (req, res) => { return new Promise((resolve, reject) => { cors(req, res, (result) => { if (result instanceof Error) { return reject(result) } return resolve(result) }) }) } export default async function handler(req, res) { const { success_url, cancel_url, amount, product } = req.body try { await runCorsMiddleware(req, res) try { const session = await stripe.checkout.sessions.create({ success_url: success_url, cancel_url: cancel_url, payment_method_types: ['card'], line_items: [ { quantity: 1, price_data: { unit_amount: amount * 100, currency: 'usd', product: product, }, }, ], mode: 'payment', }) res.status(200).json({ message: ' Stripe checkout created ok', url: session.url }) } catch (error) { res.status(500).json({ message: ' Stripe checkout error' }) } } catch (error) { res.status(403).json({ message: ' Request blocked by CORS' }) } }

En el fragmento de código anterior, debería poder ver que he definido una matriz de allowedOrigins , estos son los únicos orígenes permitidos para usar este punto final. Las solicitudes de cualquier otro origen recibirán un código de estado 403 y un mensaje de Request blocked by CORS .

Esta función también acepta una serie de parámetros del cuerpo, uno de los cuales es la amount que el "cliente" ha decidido pagar, este es el valor de la entrada HTML en el sitio MDX Embed. También notará el parámetro del product , esta es la identificación del producto definida en mi tablero de Stripe y cómo la API de Stripe crea la URL de "pago" correcta. Pasar este valor como un parámetro del cuerpo en lugar de codificarlo en la función me permite reutilizar este punto final para otros productos de Stripe.

¿Vale la pena exprimir el jugo?

He mencionado algunas cosas en el camino por las que decidí seguir esta ruta. Después de todo, puede parecer una forma más complicada de usar Serverless Functions, pero tengo mis razones y creo que vale la pena. Este es el por qué.

Paulie API es tanto una API de origen cruzado como un sitio de documentación. Naturalmente, si va a escribir una API, debe documentarse, ¿verdad?

Aquí es donde funciona a mi favor usar Gatsby para potenciar mi API porque, junto con las capacidades sin servidor, la API de Paulie también es un sitio web de Gatsby, y como en realidad es un sitio web, puedo llenarlo con contenido y hacer que se vea bonito, pero espera, hay más. …

Nota: ¡La API de Paulie también es un área de juegos API interactiva!

Cada función tiene un enlace Run in browser . Esto lo lleva a una página en el sitio donde puede interactuar con la función. Sirve como un campo de pruebas útil mientras desarrollo la función y una manera fácil de demostrar cómo funciona la función, los documentos son buenos, ¡los documentos interactivos son mejores!

También uso esta API para proporcionar una funcionalidad similar del lado del servidor para mis otros sitios web. Eche un vistazo a la página Acerca de donde he documentado cuáles de mis sitios usan qué funciones, y aquí hay un diagrama para ilustrar cómo se combina todo actualmente.

Diagrama de las funciones de origen cruzado de Paulie API
Capacidades de la función de origen cruzado de la API de Paulie. (Vista previa grande)

Debería ver en el diagrama anterior que https://paulie.dev también usa el extremo de Stripe. He usado el mismo enfoque que con MDX Embed para habilitar la funcionalidad "Pague lo que quiera". Es algo pequeño, pero dado que el punto final make-stripe-payment franjas ya está escrito y funcionando, puedo reutilizarlo y evitar la duplicación de esta funcionalidad.

El sitio web https://paulie.dev también tiene sus propias funciones sin servidor de Gatsby que utilizo para publicar las reacciones de los usuarios a Fauna y capturar las suscripciones al boletín. Esta funcionalidad es exclusiva de este sitio, por lo que aún no la he resumido. Sin embargo, si quisiera suscribirme al boletín en https://www.pauliescanlon.io, este sería el punto en el que migraría la función a la API de Paulie.

Captura de pantalla de la interfaz de usuario "Pay what you want" de paulie.dev
sección “Paga lo que quieras” de paulie.dev. (Vista previa grande)

Abstracción

Esto puede parecer un paso atrás para abstraer sus funciones sin servidor. Después de todo, una de las mejores cosas de trabajar sin servidor es que tanto el código frontal como el back-end están activos en el mismo lugar. Como he demostrado, hay momentos en los que la abstracción tiene sentido, al menos para mí.

Ciertamente me estoy beneficiando de usar este enfoque y planeo desarrollar aún más mi API para proporcionar más funcionalidad a varios de mis propios sitios web, pero si ganar dinero con el código abierto es de su interés y su sitio no está construido usando Gatsby , este enfoque bien puede ser la respuesta que estaba buscando.

¿Quieres empezar con las funciones de Gatsby? ¡Consulte los documentos de Gatsby Functions para ponerse en marcha!

Otras lecturas

Si está interesado en obtener más información sobre las funciones sin servidor, le recomiendo:

  • Libro de Swizec Teller, "Manual sin servidor para ingenieros frontend"
  • Curso de funciones de verano de Benedict
  • …y, por supuesto, los documentos de Gatsby

FuncJam

Del 17 de agosto al 30 de septiembre, la gente de Gatsby está organizando una competencia comunitaria con algunos premios absolutamente increíbles para ganar. Si todavía hay tiempo, vaya a FuncJam y únase. Además, consulte la sección Tamaño de bytes de esta publicación de blog; contiene videos útiles y enlaces a varias funciones de ejemplo.

Gracias por leer, y si desea discutir algo mencionado en este artículo, deje un comentario a continuación o búsqueme en Twitter.