Akka HTTP實戰:爲Ant Design Pro提供後端接口

實戰:爲Ant Design Pro提供後端接口

以前章節已經瞭解了Akka HTTP的路由定製、數據序列化等內容,是時候開始一個比較完整的Web應用示例了。這裏咱們將使用 Akka HTTP 來集成 Ant Design Pro ,Ant Design Pro是一個開箱即用的中臺前端/設計解決方案,它由螞蟻金服開發,官方地址:https://pro.ant.design/index-cnhtml

本文假定用戶已經熟悉並會使用 Ant Design Pro,若還未接觸過能夠從官方文檔開始:https://pro.ant.design/docs/getting-started-cn前端

本文使用 Ant Design Pro 2.0版本java

設置 Ant Design Pro

Ant Design Pro 已是一個完整的後臺前端應用,咱們只須要使用 Akka HTTP 爲其提供後端API接口服務支持和靜態資源文件的HTTP獲取功能。webpack

建立API

Akka HTTP 的 Routing DSL 是從上到下一級一級的匹配路由的,當前一個路由不匹配時才判斷下一個路由,這樣一直到最後一個。利用這個特性,咱們能夠在整個路由定義的最後來設置返回React SPA須要的靜態資源文件。git

def route: Route =
  pathPrefix("api") {
    pathGet("currentUser") {
      complete(Mocks.apiCurrentUser)
    } ~
      pathGet("fake_chart_data") {
        complete(Mocks.apiFakeChartData)
      } ~
      pathGet("tags") {
        complete(Mocks.apiTags)
      } ~
      pathGet("activities") {
        complete(Mocks.apiActivities)
      } ~
      pathGet("fake_list") {
        parameter('count.as[Int]) { count =>
          complete(Mocks.apiFakeList(count))
        }
      } ~
      pathPrefix("project") {
        pathGet("notice") {
          complete(Mocks.project.notice)
        }
      }
  } ~
    notPathPrefixTest("api") {
      getFromResourceDirectory("dist") ~
        getFromResource("dist/index.html")
    }

Full source at GitHubgithub

這裏的重點在 notPathPrefixTest(api) { .... } 部分,這一塊代碼是用來返回 Ant Design Pro 靜態資源的。首先它將判斷請求URI不是以 /api 開頭,若請求URI以/api開關則不進入裏面的獲取靜態資源代碼邏輯,而是直接返回一個預約義的指令:reject。一般,咱們都會將API接口統一到 /api 這樣的路徑下,這樣非 /api 開頭的URI請求就能夠交到下面的兩句代碼執行,來實現SPA應用在資源未找到時服務端默認返回 /index.html 的需求。web

getFromResourceDirectory("dist") ~
  getFromResource("dist/index.html")
  • getFromResourceDirectory:根據URI請求路徑從資源目錄dist查找文件並返回
  • getFromResource:直接返回 dist/index.html 資源文件

整體上,以上兩個指令組合使用就能夠實現相似 Nginx 的 try_files $uri /index.html; 效果npm

Mocks.scala,定義了API接口數據並組裝成 HttpEntity 對象。編程

object project {
  def notice = toJsonEntity(Project.notice)
}
def apiCurrentUser = toJsonEntity(Api.currentUser)
def apiFakeChartData = toJsonEntity(Api.fake_chart_data)
def apiTags = toJsonEntity(Api.tags)
def apiActivities = toJsonEntity(Api.activities)

def toJsonEntity(str: String): HttpEntity.Strict = HttpEntity(ContentTypes.`application/json`, str)

Full source at GitHubjson

這裏爲了演示Akka HTTP與Ant Design Pro的集成,我並未直接去實現後端接口數據模型的生成邏輯,好比:model定義、數據存儲操做等。而是經過直接返回字符串形式的JSON數據來模擬:

val currentUser =
  """{"name":"羊八井","avatar":"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png","userid":"00000001","email":"yangbajing@gmail.com","signature":"海納百川,有容乃大","title":"一個好爸爸","group":"華龍海數-某某某事業羣-某某平臺部-某某技術部-Developer","tags":[{"key":"0","label":"頗有想法的"},{"key":"1","label":"專一後端"},{"key":"2","label":"強~"},{"key":"3","label":"彪悍"},{"key":"4","label":"重慶崽兒"},{"key":"5","label":"海納百川"}],"notifyCount":12,"country":"China","geographic":{"province":{"label":"重慶市","key":"330000"},"city":{"label":"渝北區","key":"402260"}},"address":"渝北區金開大道西段106號10棟移動新媒體產業大廈11樓","phone":"023-88888888"}"""

Full source at GitHub

經過def toJsonEntity(str: String): HttpEntity.Strict = HttpEntity(ContentTypes.application/json, str)函數,將JSON字符串實例化爲一個HttpEntity對象並設置Content-Typeapplication/json類型。

注意

這裏只定義了Ant Design Pro的 dashboard 欄目下3個頁面須要的接口,其它接口並未實現,由於對於這個示例它們並非重點。

添加webpack proxy支持

修改 ant-design-pro/web/config/config.js 文件,在末尾右大括號(})上方添加 proxy 設置API代理訪問路徑路徑。這樣全部的前端Ajax請求(請求/api開始的路徑)都會被路由到Akka HTTP提供的API服務上。

proxy: {
    '/api': {
      target: 'http://localhost:22222',
      changeOrigin: true,
    },
  },

使用 start:no-mock 啓動Ant Design Pro

npm run start:no-mock

打開瀏覽器,訪問 http://localhost:8000 地址:

這時還未啓動Akka HTTP後端服務,看到在請求後端API /api/currentUser時報504網關超時錯誤。這表明咱們設置的 webpack.proxy 已經生效,接下來讓咱們啓動Akka HTTP後端服務。

啓動Akka HTTP Server

Main.scala

object Main extends App with StrictLogging {
  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  import system.dispatcher

  val bindingFuture = Http().bindAndHandle(handler = new Routes().route, interface = "0.0.0.0", port = 22222)

  bindingFuture.onComplete {
    case Success(binding) ⇒
      sys.addShutdownHook(system.terminate())
      logger.info(s"啓動Akka HTTP Server成功,綁定地址: $binding")
    case Failure(e) ⇒
      logger.error(s"啓動Akka HTTP Server失敗:${e.getMessage}", e)
      system.terminate()
  }

}

Full source at GitHub

能夠看到,編程啓動Akka HTTP服務很是簡單。咱們執行Main.scala便可啓動Akka HTTP服務。看到相似輸出就表明服務已經啓動成功:

10:59:13.659 [default-akka.actor.default-dispatcher-4] INFO scalaweb.ant.design.pro.Main$ - 啓動Akka HTTP Server成功,綁定地址: ServerBinding(/0:0:0:0:0:0:0:0:22222)

打包、部署

Ant Design Pro 的 Akka HTTP集成已經完成,咱們也在開發模式下分別啓動了Webpack Dev Server和Akka HTTP Server來看到咱們集成的效果。要把集成的成果部署到服務器上怎麼辦?很是的簡單,執行以下的幾行命令就能夠生成一個同時提供後端API接口和HTTP靜態資源渲染的獨立可執行jar包。不須要使用Nginx/Apache的代理靜態資源,這樣部署更加簡潔。固然,你也能夠繼續使用用Nginx/Apache來代理靜態資源,若是須要的話。

pushd ant-design-pro/web
yarn install
yarn run build
popd
rm -rf ant-design-pro/src/main/resources/dist/*
cp ant-design-pro/web/dist/* ant-design-pro/src/main/resources/dist/
sbt "project ant-design-pro" assembly
  1. 首先編譯 Ant Design Pro,在 dist 目錄生成靜態資源。
  2. copy全部靜態資源到 resources/dist 目錄,這樣Akka HTTP能夠在生成的jar裏經過Java資源文件機制訪問到它們。
  3. 使用 sbt assembly 命令打包。
  4. 使用 java -jar 命令執行可執行jar包文件。

運行程序

java -jar ant-design-pro/target/scala-2.12/ant-design-pro-assembly-1.0.0.jar

打開瀏覽器訪問 http://localhost:22222/ 便可看到 Ant Design Pro 的界面。

示例效果 

總結

咱們經過一個簡單的實戰示例:ant-desigin-pro,將以前幾章所講知識串起來經過Akka HTTP技術實現了一個較爲完整的Web應用。

本章源碼在:https://github.com/yangbajing/scala-web-development/tree/master/ant-design-pro

The source code for this page can be found here.

本文節選自《Scala Web開發》,原文連接:https://www.yangbajing.me/scala-web-development/data/data.ant-design-pro.html

相關文章
相關標籤/搜索