使用Lambda和API網關在Java中開發RESTful微服務

2021-12-09 EAWorld

本文為翻譯發表,轉載需要註明來自公眾號EAWorld。


作者:MuhammadAli 

譯者:白小白 

原題:Developing RESTful APIs in Java using Amazon APIGateway and AWS Lambda

白小白

記得之前有一位兄弟說過,寫代碼的同學最恨的就是按照一個教程一步步做,結果卡在那裡做不下去。保險起見,作為Java零基礎的小白對本文的實例進行了驗證。一些遇到卡殼的地方,以注釋的形式對原文進行了補充,當然,相關異常也可能不出現,那說明你臉比較白,自然要恭喜。小白的驗證的環境如下:Win10(64位)+Eclipse(Photon)+JavaSE8(64位)。全文的實踐要在兩個環境中進行,一是Eclipse客戶端(本地),一是在AWS的控制臺(遠程/瀏覽器訪問 https://console.aws.amazon.com/console/home )。

AWS Lambda和AmazonAPI-Gateway可用於在Java中創建RESTfulWeb服務,而無需進行複雜的Java框架配置或設置和維護Web伺服器(如Tomcat、WebSphere等)。Lambda和APIGateway的結合使得開發API變得非常容易,並且還可以輕鬆地管理API的暫存環境,比如開發、測試和Prod。

AWS Lambda是一個高度可伸縮和高度可用的無伺服器計算平臺,您可以使用它運行Java代碼來提供服務的主要功能。有關Lambda的更多信息,請訪問連結

(https://aws.amazon.com/documentation/lambda/).

AmazonAPI網關是由AWS提供的一種網絡服務,允許開發人員輕鬆地構建和部署API端點。它使開發人員非常容易地創建HTTPS端點並將其與Lambda函數集成。數據從API端點傳遞到Lambda函數,並由API網關處理。欲了解更多關於API網關的內容,請訪問連結

(https://aws.amazon.com/documentation/apigateway/).

本文提供了關於如何使用Lambda和API網關在Java中開發RESTful微服務的循序漸進的指南。

首先,您需要準備一臺開發機器,為此您需要Java 8、Eclipse IDE和AWSToolkit for Eclipse。有關如何完成此操作的詳細信息,請參閱

(https://www.bluestackcloud.com/insights/2018/5/7/getting-started-with-aws-development-using-java).

白小白

如果Marketplace閃退,在Eclipse的 Help –> Install New Software,通過在Work with處輸入 http://download.eclipse.org/mpc/photon/重新安裝。注意,在後續步驟有一個安裝組件選擇的勾選列表,如果本機沒有安裝RDS資料庫,把關於RDS這一項勾選去掉,否則後續步驟會報錯。


步驟1:(環境:Eclipse本地)創建Lambda函數

1. 一旦您準備好使用Eclipse IDE,AWS圖標將出現在主工具欄中。點擊它並選擇「新AWS Lambda項目.」

2.提供適當的項目名稱和Maven配置。選擇「Stream Request Handler」作為輸入類型。

3. 在點擊「Finish」之後,示例代碼將被加載到您新創建的項目中。打開主處理程序函數並更新以下代碼。

package com.amazonaws.lambda.demo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.Writer;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;

public class LambdaFunctionHandler implements RequestStreamHandler
{
JSONParser parser = new JSONParser();

 @Override
 public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException
 {
   LambdaLogger logger = context.getLogger();
     logger.log("Loading Java Lambda handler of ProxyWithStream");
     
     String proxy = null;
String param1 = null;
String param2 = null;

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
     JSONObject responseJson = new JSONObject();
     String responseCode = "200";
     JSONObject event = null;
     
     try {
       event = (JSONObject)parser.parse(reader);
       if (event.get("pathParameters") != null) {
         JSONObject pps = (JSONObject)event.get("pathParameters");
         if ( pps.get("proxy") != null) {
           proxy = (String)pps.get("proxy");
         }      
       }
       if (event.get("queryStringParameters") != null)
       {
         JSONObject qps = (JSONObject)event.get("queryStringParameters");
         if ( qps.get("param1") != null)
         {
           param1 = (String)qps.get("param1");
         }
       }
       if (event.get("queryStringParameters") != null)
       {
         JSONObject qps = (JSONObject)event.get("queryStringParameters");
         if ( qps.get("param2") != null)
         {
           param2 = (String)qps.get("param2");
         }
       }
       
     }
     catch(Exception pex)
     {
       responseJson.put("statusCode", "400");
       responseJson.put("exception", pex);
     }
       // Implement your logic here
      int output = 0;
      if (proxy.equals("sum"))
      {
        output = sum(Integer.parseInt(param1), Integer.parseInt(param2));
      }
      else if (proxy.equals("subtract"))
      {
        output = subtract(Integer.parseInt(param1), Integer.parseInt(param2));
      }
     
      JSONObject responseBody = new JSONObject();
        responseBody.put("input", event.toJSONString());
        responseBody.put("message", "Output is" + output);
       
        JSONObject headerJson = new JSONObject();
        headerJson.put("x-custom-header", "my custom header value");
        headerJson.put("Access-Control-Allow-Origin", "*");
       
        responseJson.put("isBase64Encoded", false);
        responseJson.put("statusCode", responseCode);
        responseJson.put("headers", headerJson);
        responseJson.put("body", responseBody.toString());
       
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
        writer.write(responseJson.toJSONString());
        writer.close();
       
 }
 public int sum(int a, int b)
 {
   return a+b;
 }
 public int subtract(int a, int b)
 {
   return a-b;
 }
}
         

(左右滑動可查看全部代碼)

白小白

首先是代碼中的類名,需要修改為第2步中的Class name,。其次是可能會遇到JSON無法解析的錯誤。需要下載JSON的包然後引入項目。引入的方法是將JSON包下載到本地,然後在項目上右鍵 –> Build Path –> Add External Achives 選擇本地包添加即可。JSON包的下載地址(http://www.java2s.com/Code/JarDownload/json-simple/json-simple-1.1.jar.zip)。如果遇到 Fatal error compiling: tools.jar not found 的報錯,從Eclipse菜單中選擇 Windows -> Preferences -> Java -> Installed JREs –> Execution Environment -> JavaSE1.x -> JDE 1.x 勾選即可。至於那個.x,我選擇的是最低版本號1.6

4. 構建並部署此Lambda函數。有關部署Java Lambda函數的完整信息可以找到這裡

(https://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-and-eclipse.html).

白小白

構建部署的方法其實很簡單,就是在項目上右鍵 –> Amazon Web Services –> Upload function to AWS Lambda。但是前提是你需要有一個AWS的帳號,並需要提供給Eclipse客戶端一個Access Key ID和Secret Access Key。這需要你在AWS的控制臺創建一個用戶,並為用戶添加 AdministratorAccess 權限,創建過程中可得到這兩個值。但要及時保存,否則在創建後,Secret Access Key是不可見的,除非在安全證書頁面重新創建訪問密鑰。上傳函數的過程,可能會有部分輸入框提示not found,此時只需要點擊其右側的create即可。

在這個例子中,我們用「REST_API_HelloWorld」的名稱在AWS控制臺中創建了Lambda函數。

步驟2:(環境:AWS控制臺/網頁)創建API網關端點

1.轉到AWS控制臺並啟動API-網關服務。

2.點擊「創建API」。

3.選擇「新API」並提供「API名稱」

4.在創建API之後,添加一個資源,如下所示:

5. 確保勾選「配置為代理資源」選項。

在下一個顯示「Any」方法設置的屏幕上,選擇「Lambda Function」作為集成類型。同時選中「Use Lambda Proxy integration」。選擇部署Lambda函數的區域,並輸入Lambda名稱。

白小白

上面的Lambda Function輸入框,可以輸入剛才上傳的函數名稱,會出現下拉列表選擇。在下一個部署API的步驟前,其實已經可以測試API是否可以正常工作,即點擊 資源 - ANY 再點擊測試,方法選擇GET ,在 路徑 處輸入 sum ,在查詢字串處輸入 param1=100&param2=100 ,點擊測試,在右側的響應正文部分,message的值應該為 "Output is 200"。如果很不幸,測試不成功,右側顯示的錯誤是:Malformed Lambda proxy response (正如第一次部署時小白所遇到的情況),可以嘗試以下方法:1、確認第4步中的Enable API Gateway CORS是否已經勾選。;2、在代碼中注釋掉 headerJson.put("Access-Control-Allow-Origin", "*"); 這句話。

6.現在,我們將把這個API部署到一個暫存環境中。為此,單擊「Action」並選擇「Deploy API」。

7.選擇[NewStage]並提供一個staging名稱和描述。在本教程中,我們使用「Dev」作為名稱。一旦部署完成,控制臺將帶您到staging頁。

8.複製「Invoke URL」,並在其上添加代理資源名稱和參數,其中包含要發送給Lambda的值。有關本教程,請參閱下面的示例:

輸出如下:

像AWS Lambda這樣的無伺服器計算平臺最近非常流行。許多組織要求他們的DevOps工程師能夠開發無伺服器應用程式,因為它減少了設置硬體/軟體基礎結構所需的時間,從而減少了項目交付時間。遵循這個簡單的教程,您應該能夠開始使用Java在AWS上開發無伺服器的微服務。

白小白

為了避免破壞原文的結構,小白的補充內容都是沒有添加截圖的,如果有什麼地方沒說明白,大家可以關注公眾號 EAWorld 戳 「加群」,然後在群內提問,只要是我遇到過的問題,我會再作進一步的解釋。

原文連結:

https://www.bluestackcloud.com/insights/2018/6/14/developing-restful-apis-in-java-using-amazon-api-gateway-and-aws-lambda

關於作者:Muhammad Ali,DevOps Engineer,BluestackCloud

關於EAWorld:微服務,DevOps,數據治理,移動架構原創技術分享,長按二維碼關注

相關焦點

  • JNPF快速開發平臺-簡單快速高效開發java項目
    JNPF快速開發平臺 JNPF快速開發平臺採用前後端分離技術、採用B/S架構開發,形成一站式開發多端(APP+PC)使用。 使用JNPF開發平臺可以簡單、快速、高效的構建各種類型java項目。
  • Laravel 開發 RESTful API 的一些心得
    驗證API 開發總會離不開驗證,這裡推薦使用jwt-auth,1.0 快要來了,新版本的文檔也很清晰剛用 jwt-auth時有疑問,Laravel自帶的token驗證使用的是資料庫apitoken欄位驗證,而不見 jwt-auth需要這個。
  • 為什麼微服務一定要有網關?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫1什麼是服務網關服務網關 = 路由轉發 + 過濾器,想讓所有的服務都去使用新的權限校驗方式,我們就需要將之前所有的服務都重新引包,編譯部署。
  • 詳解API網關核心功能和API管理擴展
    本文將詳細講解API網關的基礎概念,使用場景和核心功能,以及基於API網關核心引擎做的API全生命周期管理功能擴展等,最後介紹當前主流的開源API網關引擎。API網關概述在微服務架構體系裡面,我們一般會使用到微服務網關或叫API網關。
  • Java 微服務從源碼實戰開始|Gitee 項目推薦
    在軟體開發的不同時期、階段,對技術架構的理解、選擇和應用都有著不一樣的訴求。微服務架構是當前網際網路業界的一個技術熱點,它的思想也更符合我們的目標:根據業務模塊劃分服務種類。每個服務可以獨立部署並且互相隔離。通過輕量的 API 調用服務。服務需要保證良好的高可用性。微服務能夠使我們的開發效率更高,溝通成本更低,響應速度更快,迭代周期更短。
  • springcloud實踐二:gateway網關詳解
    微服務框架當前大行其道,網關在微服務架構中是一個非常重要的部分,網關一般作為項目的統一請求入口提供給前端開發人員,前端開發人員不用知道每個微服務的請求地址。網關可以統一對所有請求做過濾、限流、負載均衡、監控等處理,而不必在每個微服務項目重複處理請求。
  • smart-doc 1.9.4 發布,Java 零註解 API 文檔生成工具
    smart-doc是一款同時支持java restful api和apache dubbo rpc接口文檔生成的工具
  • SpringCloud:分布式微服務架構
    概念微服務是一種架構風格,它是一種將一個單一應用程式開發為一組小型服務的方法,每個服務運行在自己的進程中,服務間通信採用輕量級通信機制(通常採用http)。這些服務圍繞業務能力構建並且可通過全自動部署機制獨立部署,這些服務共用一個最小型的集中式的管理,服務可用不同的語言開發,使用不同的數據存儲技術。特徵每個微服務可獨立運行在自己的進程中。一系列獨立運行的微服務共同構建起整個系統。
  • 後端開發必備的 RestFul API 知識
    的最基本的要求(比如接口中儘量使用名詞,使用POST 請求創建資源,DELETE請求刪除資源等等,示例:GET     /notes/id:獲取某個指定id的筆記的信息)。相關閱讀:•http://www.ruanyifeng.com/blog/2014/05/restful_api.html(阮一峰,這篇文章大部分內容來源)•https://www.baeldung.com/spring-hateoas-tutorial(RestFul API Tutorial)•https://aisensiy.github.io/2017/06/04
  • smart-doc 1.9.6 發布,Java 零註解 API 文檔生成工具
    smart-doc是一款同時支持java restful api和apache dubbo rpc接口文檔生成的工具
  • Effective java-Lambda使用
    為了能根據時代發展,java 8中引入了lambda表達式。促進了java的函數編程,大大提升了開發效率。lambda表達式的出現,改變了Java開發者的編程習慣,但lambda應該如何更好的使用呢? effective java 中給出了說明。
  • 教你 10 分鐘構建一套 RESTful API 服務( 中 )
    if __name__ == '__main__':    app.run()從 flask_restful 文件中導入 Api、Resource 兩個類,使用上面的 app 對象,構建一個 api 對象,接著準備一個列表數據from flask_restful import Api,Resourceapp = Flask
  • Spring Cloud Zuul中使用Swagger匯總API接口文檔
    spring.application.name=swagger-service-aserver.port=10010eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/swagger.base-package=com.didispace
  • 10分鐘,帶你用Python構建RESTful API 服務
    if __name__ == '__main__':    app.run()從 flask_restful 文件中導入 Api、Resource 兩個類,使用上面的 app 對象,構建一個 api 對象,接著準備一個列表數據from flask_restful import Api,Resourceapp
  • 開源API網關Kong基本介紹和安裝驗證
    在GtiHub搜索API網關類的開源產品,可以看到Kong網關常年都是排第一的位置,而且當前很多都有一定研發能力的企業在API網關產品選型的時候基本也會選擇Kong網關,並基於Kong網關進行二次開發和定製。簡單來說API網關就是將所有的微服務提供的API接口服務能力全部匯聚進來,統一接入進行管理,也正是通過統一攔截,就可以通過網關實現對API接口的安全,日誌,限流熔斷等共性需求。
  • smart-doc 1.9.9 發布,Java 零註解 API 文檔生成工具
    smart-doc是一款同時支持java restful api和apache dubbo rpc接口文檔生成的工具
  • smart-doc 2.0.1 發布,Java 零註解 API 文檔生成工具
    smart-doc是一款同時支持java restful api和apache dubbo rpc接口文檔生成的工具
  • smart-doc 2.0.2 發布,Java 零註解 API 文檔生成工具
    smart-doc 是一款同時支持 java restful api 和 Apache Dubbo rpc 接口文檔生成的工具,smart-doc 顛覆了傳統類似 swagger 這種大量採用註解侵入來生成文檔的實現方法
  • Java中Lambda表達式的5種不同語法
    如果可以從上下文中推斷出參數的參數類型,則可以省略該類型。在上面的代碼中,可以將m和n的類型推斷為String,因此可以省略該類型。這使代碼更整潔,更像真正的lambda表達式。3. Lambda表達式中的多行代碼如果代碼不能一行編寫,則可以將其括在{}中。現在,該代碼應明確包含return語句。
  • Kylin的RESTful API使用
    ":false,  "project":"learn_kylin"}其中,offset為sql中相對記錄首行的偏移量,limit為限制記錄條數;二者在後臺處理時都會拼接到sql中去。/query 使用json格式的文件來執行獲取數據:curl -b cookiefile.txt -X POST -H'Content-Type: application/json' -d @mysql.json http://GPMASTER:7070/kylin/api/query附錄1: