查爾斯·厄勒(Charles Ouellet) (By Charles Ouellet)
The word serverless is buzzing through dozens of dev circles today.
如今, 無服務器一詞正在數十個開發界中流行。
It has been for a while now.
已經有一段時間了。
I’ve been meaning to exit my code editor and come talk about the trend here. Especially since I discovered Webtask, a few months ago.
我一直想退出我的代碼編輯器,然后在這里談論趨勢。 特別是自幾個月前我發現Webtask以來。
So, in between bug fixes, support & new features, I finally took some time to sit down and write a little.
因此,在錯誤修復,支持和新功能之間,我終于花了一些時間坐下來寫一點東西。
In this post, I’ll touch on serverless architectures and Backend as a Service tools a bit. But I’ll mostly focus on offering a simple yet meaningful serverless e-commerce tutorial. And I’ll use our own HTML/JS shopping cart platform & Webtask to do so.
在本文中,我將稍微介紹一下無服務器架構和后端即服務工具。 但是,我主要集中在提供一個簡單而有意義的無服務器電子商務教程。 而且,我將使用我們自己HTML / JS購物車平臺和Webtask來實現。
什么是無服務器架構,為什么要關心? (What is a serverless architecture, and why should you care?)
Like the “JAMstack”, serverless architecture is a new web development trend subscribing to the “rise of the frontend” paradigm we’re in. In layman’s terms, it’s a way to run server-side code in the cloud without worrying about web servers, routing, etc. It relies heavily on Backend as a Service (Baas) third parties such as Webtask, or the most popular kid on the block: AWS Lambda. With these BaaS services, you just write code and let them take care of all the underlying infrastructure. Scaling-wise, such an approach is quite awesome: the abstraction layer these services offer can handle peaks of traffic on your site wonderfully.
像“ JAMstack”一樣 , 無服務器架構是一種新的Web開發趨勢,它遵循了我們所處的“前端”范式。用外行的話來說,這是一種在云中運行服務器端代碼而無需擔心Web服務器的方法。 ,路由等。它在很大程度上依賴于后端即服務(Baas)第三方,例如Webtask或該區塊中最受歡迎的孩子: AWS Lambda 。 使用這些BaaS服務,您只需編寫代碼,并讓它們處理所有底層基礎結構。 在擴展方面,這種方法非常出色:這些服務提供的抽象層可以出色地處理您網站上的流量高峰。
As you may know, we’re big fans of the JAMstack (JavaScript, APIs & Markup) here at Snipcart. It’s another vibrant expression of the “rise of the frontend” paradigm I mentioned. We’ve written whole tutorials on how to run e-commerce with static site generators such as Jekyll or Hugo, and even with API-first CMS like Contentful. From cost to tech stacks shifts, I believe such an approach will deeply impact how businesses handle web development in the next years.
如您所知,我們是Snipcart的JAMstack (JavaScript,API和標記)的忠實擁護者。 這是我提到的“前端崛起”范式的又一個生動表達。 我們已經編寫了完整的教程,介紹如何使用靜態網站生成器(例如Jekyll或Hugo ,甚至使用像Contentful這樣的API優先CMS)來運行電子商務。 從成本到技術堆棧的轉變,我相信這種方法將在未來幾年深刻影響企業處理Web開發的方式。
However, I’m aware that it has its limits: a modern static site is raw content, which means using dynamic features such as webhooks would be impossible without some server-side code. That’s where Webtask comes in.
但是,我知道它有其局限性:現代的靜態網站是原始內容 ,這意味著如果沒有一些服務器端代碼,就不可能使用諸如webhooks之類的動態功能。 這就是Webtask出現的地方。
Webtask:目標任務(或FaaS)的后端即服務 (Webtask: Backend-as-as-Service for Targeted Tasks (or FaaS))
Webtask is a neat service crafted by Auth0, the good folks who made a serious dent in the online authentication world. Acting as a Function as a Service, it basically removes the need to configure a backend for simple mobile or single-page apps. Often compared to AWS Lambda, it allows developers to write server-side logic & functions executed via HTTP calls. So it’s one of the best Backend as a Service tools out there for developers who’d rather focus on the frontend than configure the backend.
Webtask是Auth0精心制作的一項精美服務, Auth0是在在線身份驗證世界中大受打擊的好伙伴 。 作為功??能即服務,它基本上消除了為簡單的移動或單頁面應用程序配置后端的需要。 與AWS Lambda相比 ,它通常使開發人員可以編寫通過HTTP調用執行的服務器端邏輯和功能。 因此,對于那些寧愿專注于前端而不是配置后端的開發人員來說,它是最好的后端即服務工具之一。
Now let’s see how perfect it is for the use case we’ll explore in this serverless tutorial.
現在,讓我們看看在本無服務器教程中將探討的用例有多完美。
無服務器電子商務教程:webhooks和自定義運費 (Serverless e-commerce tutorial: webhooks & custom shipping rates)
At Snipcart, I believe one of our most powerful features is the Webhooks Shipping API. Simply put, it gives you full control on how your e-commerce site handles shipping.
在Snipcart,我相信我們最強大的功能之一就是Webhooks Shipping API 。 簡而言之,它使您可以完全控制電子商務網站如何處理運輸。
However, leveraging this feature requires running server-side code. So if you wanted to use a JAMstack set up with a static site generator, you’d be screwed. Thanks to Webtask, however, you’re not! In this serverless tutorial, we’ll use it to host the e-commerce shipping function we need directly via their platform.
但是,利用此功能需要運行服務器端代碼。 因此,如果您想使用帶有靜態站點生成器的JAMstack設置,那將會很麻煩。 幸虧有了Webtask,您不是! 在本無服務器教程中,我們將使用它直接通過其平臺托管我們需要的電子商務運送功能。
我們簡單的無服務器電子商務用例 (Our simple serverless e-commerce use case)
Now, let’s pretend we have a static e-commerce site running with Snipcart.
現在,讓我們假設我們有一個與Snipcart一起運行的靜態電子商務網站。
And let’s say we want to offer three special shipping rates:
假設我們要提供三種特殊的運費:
- One for customers in our Québec hometown 在魁北克故鄉為客戶提供的一種
- One for US customers 一個給美國客戶
- One for all other international customers 一個供所有其他國際客戶使用
1.如何創建Webtask功能 (1. How to create the Webtask function)
First of all, let me explain a little how our shipping API works. Snipcart sends all the order details to a URL you can specify in your merchant dashboard. Using this data, you can then write code to return available shipping rates to your end customers.
首先,讓我解釋一下我們的運輸API如何工作。 Snipcart將所有訂單詳細信息發送到您可以在商家信息中心中指定的URL。 然后,使用這些數據,您可以編寫代碼以將可用的運費退還給最終客戶。
Start by creating an account on https://webtask.io/. Once it’s done, follow their steps to install the Webtask CLI via npm
.
首先在 https://webtask.io/ 上創建一個帳戶 。 完成后,請按照他們的步驟通過 npm
安裝Webtask CLI 。
We’ll now create a file named shipping_task.js
. It'll contain all the code needed to parse the order details received from Snipcart and return the available shipping rates.
現在,我們將創建一個名為shipping_task.js
的文件。 它包含解析從Snipcart收到的訂單詳細信息并返回可用運費的所有代碼。
Let’s start by exporting a module that Webtask will understand.
讓我們從導出Webtask可以理解的模塊開始。
module.exports = function (context, cb) {cb(null, context.body);
}
The first parameter, context, contains the data Snipcart will send to your application. Webtask takes care of parsing the JSON, and you can access all the event details along with the order via context.body.
第一個參數context是包含Snipcart將發送到您的應用程序的數據。 Webtask負責解析JSON,您可以通過context.body訪問所有事件詳細信息以及順序。
With the code above, our task would return the request body that it received; pretty useless. ;)
使用上面的代碼,我們的任務將返回它收到的請求正文; 真沒用。 ;)
Now let’s say we want to offer free shipping for customers in Québec.
現在,我們要為魁北克的客戶提供免費送貨。
module.exports = function (context, cb) {var orderDetails = context.body.content;var rates = [];var address = orderDetails.shippingAddress || order.billingAddress;if (address.country == "CA" && address.province == "QC") {rates.push({cost: 0,description: "Free shipping for Québec residents!"});}cb(null, { rates: rates });
}
Ain’t that nice? However, with this code, customers outside Québec won’t have any shipping options. So we’ll make sure to return a standard shipping rate in case the order does not match our conditions:
那不是很好嗎? 但是,使用此代碼,魁北克省以外的客戶將沒有任何運送選擇。 因此,如果訂單不符合我們的條件,我們將確保返回標準的運費:
if (rates.length === 0) {rates.push({cost: 20,description: "Standard shipping"});
}
You can see below the complete code with some additional conditions:
您可以在完整的代碼下方看到一些附加條件:
module.exports = function (context, cb) {console.log(context.body);var orderDetails = context.body.content;var rates = [];var address = orderDetails.shippingAddress || order.billingAddress;if (address.country == "CA" && address.province == "QC") {rates.push({cost: 0,description: "Free shipping for Québec residents!"});}if (address.country == "CA" && address.province != "QC") {rates.push({cost: 10,description: "Shipping to Canada"});}if (address.country == "US") {rates.push({cost: 15,description: "Shipping to US"});}if (rates.length === 0) {rates.push({cost: 20,description: "Standard shipping"});}cb(null, { rates: rates });
}
Webtask will then generate a URL; you should see it in your terminal.
然后,Webtask將生成一個URL。 您應該在終端中看到它。
Simply use this URL and when configuring the Webhooks Shipping API.
在配置Webhooks運送API時,只需使用此URL。
2.保護無服務器組件 (2. Securing the serverless component)
With our current set up, anyone could send requests to this API, right? That’s not something we want. So we’ll make sure that the function only handles requests coming from Snipcart. We’ll use our request validation API to do so.
通過我們當前的設置,任何人都可以向該API發送請求,對嗎? 那不是我們想要的東西。 因此,我們將確保該函數僅處理來自Snipcart的請求。 我們將使用請求驗證API來執行此操作。
First, we’ll need to send a Snipcart secret API key to the task in order to call the request validation API. We don’t want to expose it directly through the code, so we’re going to use the secrets
feature that Webtask has. It allows us to pass secret parameters to the task that will be encrypted and accessible via the context
object.
首先,我們需要向任務發送Snipcart秘密API密鑰,以調用請求驗證API。 我們不想直接通過代碼公開它,因此我們將使用Webtask具有的secrets
功能。 它允許我們將秘密參數傳遞給將被加密并可以通過context
對象訪問的任務。
When creating the task, I added the --secret
switch:
創建任務時,我添加了--secret
開關:
wt create shipping_task.js — secret snipcartApiKey=MY_SECRET_API_KEY
You will then be able to access this value using context.secrets.snipcartApiKey
. We'll also use the request
module, so we'll need to require it at the beginning of the file:
然后,您將可以使用context.secrets.snipcartApiKey
訪問此值。 我們還將使用request
模塊,因此我們需要在文件開頭要求它:
var request = require('request');
When we make requests to your Webhooks, we always include a request token in the request headers. The header is named X-Snipcart-RequestToken
. We'll access it through our context
object again:
當我們向您的Webhooks發出請求時,我們總是在請求標頭中包含一個請求令牌。 標頭名為X-Snipcart-RequestToken
。 我們將再次通過context
對象訪問它:
var requestToken = context.headers['x-snipcart-requesttoken'];
Please note that all the headers are in lower cases with Webtask.
請注意,Webtask的所有標頭均小寫。
Here are the options we’ll use to send the request to our API:
以下是我們用于將請求發送到我們的API的選項:
var requestToken = context.headers['x-snipcart-requesttoken'];
var secretApiKey = context.secrets.snipcartApiKey;var requestOptions = {url: 'https://app.snipcart.com/api/requestvalidation/' + requestToken,headers: {"Accept": "application/json"},auth: {user: secretApiKey}
};
We’ll run this request and only execute the code in the callback if it’s successful.
我們將運行此請求,僅在成功的情況下在回調中執行代碼。
request(requestOptions, function(error, response, body) {if (response.statusCode === 200) {// Return rates} else {// Return an error when the request does not come from Snipcart. cb("Only Snipcart can call this code!");}
});
So my whole function now looks like this:
所以我的整個函數現在看起來像這樣:
var request = require('request');module.exports = function (context, cb) {var requestToken = context.headers['x-snipcart-requesttoken'];var secretApiKey = context.secrets.snipcartApiKey;var requestOptions = {url: 'https://app.snipcart.com/api/requestvalidation/' + requestToken,headers: {"Accept": "application/json"},auth: {user: secretApiKey}};request(requestOptions, function(error, response, body) {if (response.statusCode === 200) {var orderDetails = context.body.content;var rates = [];var address = orderDetails.shippingAddress || order.billingAddress;if (address.country == "CA" && address.province == "QC") {rates.push({cost: 0,description: "Free shipping for Québec residents!"});}if (address.country == "CA" && address.province != "QC") {rates.push({cost: 10,description: "Shipping to Canada"});}if (address.country == "US") {rates.push({cost: 15,description: "Shipping to US"});}if (rates.length === 0) {rates.push({cost: 20,description: "Standard shipping"});}cb(null, { rates: rates });}else {cb("Only Snipcart can call this code!");}});
}
Webtask結束語和無服務器方法 (Closing words on Webtask & the serverless approach)
Coming up with this little Webtask function for a static site running Snipcart took me less than two hours. Of course, we could’ve focused on other e-commerce functions: handling webhooks to make the bridge between Snipcart and external accounting systems, automating digital goods delivery, and more.
對于運行Snipcart的靜態網站,想出了這個小的Webtask功能,花了我不到兩個小時的時間。 當然,我們本可以專注于其他電子商務功能:處理Webhooks以在Snipcart和外部會計系統之間架起橋梁,實現數字商品交付的自動化等。
I really believe there are tons of exciting serverless use cases developers should try to handle with Auth0’s Webtask. Any integration with an API, or delegating more long-running/CPU-consuming jobs would make much sense!
我真的相信開發人員應該嘗試使用Auth0的Webtask處理大量令人興奮的無服務器用例。 與API進行任何集成,或委派更多長時間運行/占用CPU的作業都非常有意義!
The serverless approach is gearing up to have quite an impact on our work as developers. As we’re now seeing with RESTful APIs, many services will start relying on functions developed or hosted by others. The near future will bring more and more microservices hosted in environments like Webtask & AWS Lambda. Especially coupled with the rise of frameworks like Vue & the JAMstack.
無服務器方法正在加速發展,對我們作為開發人員的工作產生很大影響。 正如我們現在使用RESTful API所看到的那樣,許多服務將開始依賴于其他人開發或托管的功能。 在不久的將來,將在Webtask和AWS Lambda等環境中托管越來越多的微服務。 特別是隨著Vue和JAMstack等框架的興起。
So I sincerely hope this post inspires developers to leverage the FaaS power of Webtask on different serverless projects, e-commerce or not. And of course, I’d be more than interested to have a look at such set ups. You can shoot us an email at geeks@snipcart.com if you got something similar to share, or if you have questions regarding this approach!
因此,我衷心希望這篇文章能激發開發人員在不同的無服務器項目(無論是否為電子商務)中利用Webtask的FaaS功能。 當然,我對研究這樣的設置非常感興趣。 如果您有類似的分享內容,或者對這種方法有疑問,可以通過geeks@snipcart.com向我們發送電子郵件。
Liked the post? Take a second to ? and share it on Twitter!
喜歡這個職位嗎? 花一秒鐘來? 并在Twitter上分享 !
Originally published on the Snipcart blog and in our newsletter.
最初發布在 Snipcart博客 和 我們的時事通訊中 。
翻譯自: https://www.freecodecamp.org/news/webtask-backend-as-a-service-quick-serverless-tutorial/