代碼片段輕松編寫(xiě)你的第一個(gè) REST API)
elli 快速上手指南10 個(gè)代碼片段輕松編寫(xiě)你的第一個(gè) REST API【免費(fèi)下載鏈接】elliSimple, robust and performant Erlang web server項(xiàng)目地址: https://gitcode.com/gh_mirrors/ell/ellielli 是一個(gè)簡(jiǎn)單、穩(wěn)健且高性能的 Erlang Web 服務(wù)器專(zhuān)為高吞吐、低延遲的 HTTP API 場(chǎng)景而生。如果你正在尋找一個(gè)輕量級(jí)的 Erlang HTTP 服務(wù)器來(lái)搭建 REST APIelli 無(wú)疑是值得一試的選擇它沒(méi)有厚重的框架包袱核心只是一個(gè)回調(diào)Callback模型配合 rebar 幾分鐘就能跑起來(lái)。本文將通過(guò) 10 個(gè)可直接復(fù)用的代碼片段帶你從零上手 elli快速編寫(xiě)出你的第一個(gè) REST API。 elli 是什么為什么選擇它elli 的定位非常純粹只做 Web 服務(wù)器該做的事HTTP 解析、連接管理、響應(yīng)輸出業(yè)務(wù)邏輯全部交給你自己的回調(diào)模塊。它的特點(diǎn)包括特性說(shuō)明 簡(jiǎn)單只需實(shí)現(xiàn)handle/2和handle_event/3兩個(gè)回調(diào)函數(shù)? 高性能默認(rèn) 20 個(gè) acceptor 進(jìn)程并發(fā)接受連接底層直接操作 socket? 穩(wěn)健對(duì)異常請(qǐng)求、客戶(hù)端斷開(kāi)、超時(shí)都有完善的事件通知機(jī)制 可擴(kuò)展中間件機(jī)制支持請(qǐng)求預(yù)處理、響應(yīng)后處理如自動(dòng) gzip當(dāng)前版本為 1.0.5采用 MIT 協(xié)議可以放心用于商業(yè)項(xiàng)目。 第一步獲取源碼并編譯ell 項(xiàng)目使用 rebar 構(gòu)建克隆倉(cāng)庫(kù)后直接編譯即可git clone https://gitcode.com/gh_mirrors/ell/elli cd elli make compile編譯完成后ebin/目錄下就是編譯好的 beam 文件。項(xiàng)目自帶rebar腳本無(wú)需額外安裝構(gòu)建工具。你可以把ebin加入 Erlang 的代碼路徑-pa ebin或者通過(guò) rebar 的deps機(jī)制引入到自己的項(xiàng)目中。 核心概念回調(diào)模塊elli 的設(shè)計(jì)思想是服務(wù)器框架 你的回調(diào)模塊。你的模塊只需遵循src/elli_handler.erl中定義的 behaviour實(shí)現(xiàn)兩個(gè)函數(shù)handle/2處理每個(gè) HTTP 請(qǐng)求返回響應(yīng)handle_event/3接收啟動(dòng)、請(qǐng)求完成、異常等事件通知下面這個(gè)最簡(jiǎn)模塊就是完整的Hello World-module(my_callback). -behaviour(elli_handler). -export([handle/2, handle_event/3]). handle(Req, _Args) - {ok, [], Hello, World!}. handle_event(_Event, _Data, _Args) - ok.啟動(dòng)服務(wù)器同樣簡(jiǎn)單在你的 supervisor 或測(cè)試 shell 中elli:start_link([{callback, my_callback}, {port, 8080}]).訪問(wèn)http://localhost:8080/就能看到響應(yīng)了。? 10 個(gè)代碼片段從入門(mén)到進(jìn)階片段 1最小的 Hello World 服務(wù)這是最基礎(chǔ)的形式返回{ok, Headers, Body}三元組。ok等價(jià)于狀態(tài)碼200Headers為空列表表示不附加任何響應(yīng)頭handle(_Req, _Args) - {ok, [], Hello, World!}.也可以省略狀態(tài)碼簡(jiǎn)寫(xiě)為{200, hello}見(jiàn)src/elli_example_callback.erl中的shorthand路由。片段 2按方法與路徑路由分發(fā)elli 最大的樂(lè)趣在于路由就是模式匹配。elli_request:path/1會(huì)把 URL 路徑拆成二進(jìn)制列表配合 HTTP 方法直接匹配handle(Req, _Args) - handle(Req#req.method, elli_request:path(Req), Req). handle(GET, [users], _Req) - {ok, [], user list}; handle(GET, [users, Id], _Req) - {ok, [], user: , Id/binary}; handle(_, _, _Req) - {404, [], Not Found}.無(wú)需任何路由框架一個(gè)函數(shù)頭就是一個(gè)路由規(guī)則清晰又高效。片段 3讀取 GET 查詢(xún)參數(shù)elli_request:get_arg/3從 URL 查詢(xún)字符串取值第三個(gè)參數(shù)是默認(rèn)值get_arg_decoded/3則自動(dòng)做 URL 解碼handle(GET, [hello], Req) - Name elli_request:get_arg(name, Req, world), {ok, [], Hello , Name/binary};訪問(wèn)/hello?nameelli會(huì)返回Hello elli。片段 4讀取 POST 表單參數(shù)POST 表單application/x-www-form-urlencoded同樣一條 API 搞定handle(POST, [users], Req) - Name elli_request:post_arg(name, Req, anonymous), {ok, [], created user: , Name/binary};需要解碼時(shí)使用post_arg_decoded/3所有解析邏輯封裝在src/elli_request.erl中開(kāi)箱即用。片段 5設(shè)置響應(yīng)頭與內(nèi)容協(xié)商通過(guò)響應(yīng)頭可以輕松實(shí)現(xiàn)內(nèi)容協(xié)商根據(jù)客戶(hù)端的Accept頭返回不同格式handle(GET, [info], Req) - case elli_request:get_header(Accept, Req, text/plain) of application/json - {ok, [{Content-Type, application/json}], {\lang\:\erlang\}}; _ - {ok, [{Content-Type, text/plain}], lang: erlang} end.片段 6返回 JSON 數(shù)據(jù)結(jié)合jsx或jsone等 JSON 庫(kù)返回 JSON 只需設(shè)置正確的Content-Typehandle(GET, [users, Id], _Req) - Body jsx:encode([{id, Id}, {name, elli}]), {ok, [{Content-Type, application/json}], Body};片段 7重定向 302 與 304 Not Modified設(shè)置Location頭即可實(shí)現(xiàn)重定向返回304時(shí) elli 會(huì)自動(dòng)不發(fā)送響應(yīng)體配合自定義Etag頭非常適合做緩存handle(GET, [redirect], _Req) - {302, [{Location, /users}], }; handle(GET, [cached], _Req) - {304, [{Etag, abc123}], ignored};片段 8統(tǒng)一 404 與異常處理兜底子句返回 404而在回調(diào)中throw異常時(shí)elli 會(huì)返回 500 并觸發(fā)request_throw事件方便你記錄日志handle(_, _, _Req) - {404, [], Not Found}; handle(GET, [crash], _Req) - throw(something_went_wrong).更妙的是你還可以在throw里直接帶狀態(tài)碼實(shí)現(xiàn)短路的授權(quán)攔截throw({403, [], Forbidden}).片段 9流式 chunked 響應(yīng)SSEelli 原生支持 chunked 傳輸適合做 Server-Sent Events 或?qū)崟r(shí)推送。返回{chunk, Headers}后在任意進(jìn)程中發(fā)送數(shù)據(jù)塊handle(GET, [events], Req) - Ref elli_request:chunk_ref(Req), spawn(fun() - send_events(Ref) end), {chunk, [{Content-Type, text/event-stream}]}. send_events(Ref) - elli_request:send_chunk(Ref, [data: ping\n\n]), timer:sleep(1000), elli_request:close_chunk(Ref).參考src/elli_example_callback.erl中的chunk_loop/1它演示了循環(huán)發(fā)送 10 個(gè)數(shù)據(jù)塊的完整寫(xiě)法。片段 10中間件與 gzip 壓縮elli 的中間件機(jī)制讓功能擴(kuò)展變得優(yōu)雅。將{callback, elli_middleware}與{mods, [...]}組合即可串聯(lián)多個(gè)處理模塊Config [ {mods, [ {my_auth_middleware, []}, %% 自定義中間件 {elli_middleware_compress, []}, %% 自動(dòng) gzip {my_callback, []} %% 最終業(yè)務(wù)回調(diào) ]} ], elli:start_link([{callback, elli_middleware}, {callback_args, Config}, {port, 8080}]).其中elli_middleware_compress會(huì)自動(dòng)對(duì)超過(guò) 1024 字節(jié)的響應(yīng)體做 gzip 壓縮參考src/elli_middleware_compress.erl你的業(yè)務(wù)代碼完全無(wú)感知。中間件返回ignore時(shí)請(qǐng)求會(huì)繼續(xù)傳遞給下一個(gè)模塊實(shí)現(xiàn)短路與分流。?? 常用配置項(xiàng)一覽啟動(dòng) elli 時(shí)通過(guò) proplist 傳入配置見(jiàn)src/elli.erl的初始化邏輯配置項(xiàng)默認(rèn)值說(shuō)明callback必填回調(diào)模塊名port8080監(jiān)聽(tīng)端口min_acceptors20acceptor 進(jìn)程數(shù)越大并發(fā)越高request_timeout60000整體請(qǐng)求超時(shí)毫秒header_timeout10000讀取請(qǐng)求頭超時(shí)body_timeout30000讀取請(qǐng)求體超時(shí)max_body_size1024000請(qǐng)求體大小上限字節(jié)ssl/keyfile/certfilefalse啟用 HTTPS 監(jiān)控與運(yùn)維小貼士elli 提供了幾個(gè)實(shí)用的管理 APIelli:get_acceptors(Pid). %% 查看當(dāng)前 acceptor 進(jìn)程數(shù) elli:get_open_reqs(Pid). %% 查看正在處理的請(qǐng)求數(shù) elli:set_callback(Pid, NewMod, Args). %% 熱更新回調(diào)模塊配合handle_event/3中的request_complete事件包含請(qǐng)求各階段的時(shí)間戳你可以收集請(qǐng)求耗時(shí)搭建自己的監(jiān)控看板。 總結(jié)通過(guò)這 10 個(gè)代碼片段你應(yīng)該已經(jīng)感受到 elli 的簡(jiǎn)潔與強(qiáng)大純 Erlang 模式匹配式路由、零依賴(lài)的回調(diào)設(shè)計(jì)、完善的超時(shí)與異常事件體系讓 REST API 開(kāi)發(fā)回歸本質(zhì)。無(wú)論是快速原型還是高并發(fā)生產(chǎn)服務(wù)elli 都是 Erlang 生態(tài)里值得信賴(lài)的選擇?,F(xiàn)在就克隆項(xiàng)目把第一個(gè){ok, [], Hello}跑起來(lái)吧【免費(fèi)下載鏈接】elliSimple, robust and performant Erlang web server項(xiàng)目地址: https://gitcode.com/gh_mirrors/ell/elli創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考