用 Deno 編寫一個簡單的 REST API
800
2025-04-01
有人的地方就有江湖,有江湖的地方就有爭論。前些天,繼《[譯]為什么如今 Deno 正全面取代 Node.js》之后,又有了《【譯】Deno 已經死了嗎?》,也許這便是江湖。說回標題”Deno 在手,天下我有“,其實 Deno 換成Charj、NodeJS、Java 等其他名詞都一樣,畢竟只是標題罷了,可能真正不一樣的是使用她的愉悅感。對我而言,能給我帶來 Copy 的快感,便是極好的!
源起
本周,被@justjavac 巨佬的各個熱搜榜項目吸睛了,抱著對技術的三分鐘熱情以及對優秀代碼的學習心切,我又開始了新的代碼拷貝旅程。二話不說,先git clone一頓操作猛如虎,定睛一看,好像這幾個項目的實現都差不多,也請教了巨佬本尊確定實現是一樣的,但為毛要開 4 個 repo 呢?也許這就是單一職責原則吧。然后,我尋思著能不能整合一下再加點別的熱搜榜就能變成trending in one,是不是很棒的想法,哈哈哈哈。接下來,我還會對今日頭條下手--”得熱搜者得天下,熱搜榜拿來吧!“,三下除二拿到了頭條熱搜榜(盡管需要輸入圖片驗證碼)。最后就是資源整合,不過發現 README.md 爆了,看來單例還是有單例的好。
即刻獲取今日熱搜榜 ?? trending-in-one
剖析
其實拋開語言和平臺,要想實現熱搜匯總榜,無非就是三步走:① 獲取數據 ② 處理數據 ③ 輸出數據。接下來從 Deno 的視角來詳細解說這三步是如何走的:
獲取數據
當我們遇到一個需求,可能要從它的本質出發,比如要實現熱搜匯總,首先我們就需要各大平臺的熱搜數據,如今日頭條熱搜榜、知乎熱門視頻、知乎熱門話題、知識熱門搜索、微博熱門搜索等等,怎么獲取呢?常規的手段就是框按 F12 看看 Network,實在不行試試抓包工具.好在“前人栽樹后人乘涼”,于是乎我們便有了各平臺的接口,獲取數據豈不是信手沾來。
頭條熱榜:https://is-lq.snssdk.com/api/suggest_words/?business_id=10016
微博熱搜:https://s.weibo.com/top/summary
知乎熱門話題:https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=100
知乎熱門視頻:https://www.zhihu.com/api/v3/feed/topstory/hot-lists/zvideo?limit=100
知乎熱搜: https://www.zhihu.com/api/v4/search/top_search
當然以上接口并非永久有效,目前來看也只能是能用多久用多久了,如果您不滿足于此,亦可以試試Twitter、Medium 等等(PS:好人一生平安)。不過,上邊的接口中,微博熱搜特立獨行,她返回的是 HTML 需要用到正則匹配即可拿到熱搜標題和鏈接,正則可把我難住了:/(.+)<\/a>/g,似懂非懂。各位少俠可否移步評論區多多指教?
以今日頭條為例,獲取數據似乎顯示特別簡單,但捫心自問 await、fetch、TypeScript 我又了解多少呢?
const?response?=?await?fetch(
"https://is-lq.snssdk.com/api/suggest_words/?business_id=10016",
);
if?(!response.ok)?{
console.error(response.statusText);
Deno.exit(-1);
}
const?result:?ToutiaoTopSearch?=?await?response.json();
const?words?=?result.data[0].words;
處理數據
最終我們的數據可能是這樣的--參見2020-12-01 頭條熱搜
細心的小伙伴也許看到了.md 文件中的注釋,就是這注釋起到了關鍵的作用,移花接木?為他人做嫁衣?在進行數據更新的時候,我們可以巧妙地利用注釋作為參照,動態替換注釋開頭和注釋結尾中間的內容,利用 Deno 標準庫及一些內置 API 完成文件操作,比如今日頭條熱搜數據的創建及更新:
export?function?createTuotiaoList(words:?ToutiaoWord[]):?string?{
return?`
${
words.map((x)?=>?`1.?[${x.word}](${x.url})`)
.join("\n")
}
`;
}
export?async?function?createReadme4Toutiao(
words:?ToutiaoWord[],
):?Promise
const?readme?=?await?Deno.readTextFile("./README.md");
return?readme.replace(
/[\W\w]*/,
createTuotiaoList(words),
);
}
另外再對比新舊數據的時候,用到了常用的數組迭代方法及**Object.entries()** ,感覺 MDN 還得多刷,完全不熟練,尤其是串起來的時候:
/**?合并兩次熱搜并去重?*/
export?function?mergeWords4Toutiao(
words:?ToutiaoWord[],
another:?ToutiaoWord[],
):?ToutiaoWord[]?{
const?obj:?Record
for?(const?w?of?words.concat(another))?{
obj[w.url]?=?w.word;
}
return?Object.entries(obj).map(([url,?word])?=>?({
url,
word,
}));
}
輸出數據
其實在處理數據的時候,我們基本完成了數據輸出的準備工作,鑒于本項目中只輸出為.md 文件和.json 文件,直接調用之前的處理數據方法即可,簡單粗暴:
export?async?function?toutiaoSearch()?{
//?保存原始數據
await?Deno.writeTextFile(fullPath,?JSON.stringify(wordsAll));
//?更新?README.md
const?readme?=?await?createReadme4Toutiao(wordsAll);
await?Deno.writeTextFile("./README.md",?readme);
//?更新?archives
const?archiveText?=?createArchive4Toutiao(wordsAll,?yyyyMMdd);
const?archivePath?=?join("archives/toutiao-search",?`${yyyyMMdd}.md`);
await?Deno.writeTextFile(archivePath,?archiveText);
}
如果不局限于輸出數據為文件,我們可以實現的功能就可以多了,發送熱搜數據(或者任何您能獲取到的數據)到郵件、短信、釘釘機器人……不禁又想起了老濕常說的“帶薪拉屎”必備,想想每天早上第一泡就能享用熱乎的熱搜榜,似乎有種“家事國事天下事,事事關心”的錯覺,坐著點開一條條熱搜表示“朕已閱”……
Github Action
如果說 Serverless 是個好東西,那么Github Action怎么逃得過真香定律呢?在 GitHub Actions 的倉庫中自動化、自定義和執行軟件開發工作流程。您可以發現、創建和共享操作以執行您喜歡的任何作業(包括 CI/CD),并將操作合并到完全自定義的工作流程中。通俗點就是您可以為所欲為,比如定時構建 Deno 應用。為了能夠每小時更新我們的熱搜匯總,我們需要給 github 倉庫新增**.github/workflows** 文件夾,也就是前邊所說的工作流 ,然后新建 ci.yml 和 schedule.yml 告訴 Github Action 應該如何做,這樣她就是聽話的貼心小秘書了,因為她會告訴您每一次執行工作流的詳細結果,就算構建失敗也有郵件溫馨提醒。至于 yml 的內容應該寫啥,請參照官方文檔和 Deno 社區經典案例(PS:好像是我的知識盲區,用得還不熟練,怕帶坑)。 當然,如果想直接開干的話,可以在倉庫的 Action 選項卡中獲取到 github 提供的溫馨建議。少年,亮劍吧!
尾聲
探索的腳步永不止步,不過于我,好像置身于小黑屋,無論我怎么走都無法走出去,十多年了,依舊原地踏步踏。小時候,夢想長大以后一家子各兄弟能大干一場實現家族企業的幻想卻奈何爺輩早逝凝聚力盡失;到中學,懷恨于內心的脆弱被班主任拿捏死失去重點中學的入場券落為雞頭放棄自我;萬幸有的大學讀,卻虛度光陰于網吧、操場、情人坡、后山,終費萬事……到此刻及未來,終究要為過去的沉淪頹廢而埋單。唉,年紀大了,還能怎么折騰?謹以此段,奉勸家中無礦、朝中無權的年輕人,莫虛度此生,至少 Deno 真香!
完整項目地址: https://github.com/hu-qi/trending-in-one
JavaScript
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。