以前章節已經瞭解了Akka HTTP的路由定製、數據序列化等內容,是時候開始一個比較完整的Web應用示例了。這裏咱們將使用 Akka HTTP 來集成 Ant Design Pro ,Ant Design Pro是一個開箱即用的中臺前端/設計解決方案,它由螞蟻金服開發,官方地址:https://pro.ant.design/index-cn。html
本文假定用戶已經熟悉並會使用 Ant Design Pro,若還未接觸過能夠從官方文檔開始:https://pro.ant.design/docs/getting-started-cn。前端
本文使用 Ant Design Pro 2.0版本java
Ant Design Pro 已是一個完整的後臺前端應用,咱們只須要使用 Akka HTTP 爲其提供後端API接口服務支持和靜態資源文件的HTTP獲取功能。webpack
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)
這裏爲了演示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"}"""
經過def toJsonEntity(str: String): HttpEntity.Strict = HttpEntity(ContentTypes.
application/json, str)
函數,將JSON字符串實例化爲一個HttpEntity
對象並設置Content-Type
爲application/json
類型。
注意
這裏只定義了Ant Design Pro的 dashboard 欄目下3個頁面須要的接口,其它接口並未實現,由於對於這個示例它們並非重點。
修改 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後端服務。
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() } }
能夠看到,編程啓動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
dist
目錄生成靜態資源。resources/dist
目錄,這樣Akka HTTP能夠在生成的jar裏經過Java資源文件機制訪問到它們。sbt assembly
命令打包。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