包含標籤 api 的文章

使用 JMeter 來對 API 壓力測試吧

Image

前陣子協助某支 API 的壓力測試,趁機請 QA 朋朋指導指導一下,因此接觸了這款簡單好用的壓測工具 JMeter,趁現在記憶還在的時候記錄起來。

往後其他同事只要說 API 弄好了可以串了,就先幫他打個一萬次壓壓驚,真是貼心

JMeter 是款充滿暴力的壓力測試工具,只要告訴他:你要揍哪支 API?要揍幾拳?揍他個幾輪?它就會忠實地對你指定的 API 爆打一頓。

……

閱讀全文


C#: 使用 AngleSharp 爬蟲工具來抓取網頁內容吧

Image

前一次用到 AngleSharp 已經是去年抓網路小說的時候,想不到最近又用上了,乾脆就來筆記一下。

AngleSharp 是一款簡單方便的 C# 爬蟲套件,撈網頁時支援 QuerySelector 的語法來篩選網頁元素,並且撈回來的資料集合也都能用 Linq 操作,讓我們能對爬取的網頁內容快速進行篩選和處理,只需要短短的語法就可以開心抓想要的內容。

說到要示範爬蟲,果然還是要用爬蟲界默認的經典範例 PTT 表特版 來操作(?),接著就讓我們來寫一個簡單的腳本來抓取文章吧!

……

閱讀全文


菜雞新訓記 (5): 使用 三層式架構 來切分服務的關注點和職責吧

img

這是俺整理公司新訓內容的第五篇文章,目標是使用三層式架構 (3-Layer Architecture) 來切分服務的關注點和職責

什麼是分層?分層可以吃嗎?

天地混沌如雞子,商業邏輯生其中。

萬八千歲,天地開闢。表現層為天。資料層為地。商業邏輯層在其中……

    --民明書坊《盤古與他的CRUD之旅》

根據民明書坊的文獻記載,我們常聽到的「天地玄黃,宇宙洪荒」云云,其實指的就是上古時期的開發狀況。當時世界還是一片混沌,所有的程式碼都混雜成一坨,不是所有東西寫在一起你儂我儂,一言不合就三千行;就是依賴關係交錯複雜,改了北極壞南極。

要說有多亂呢,大概就算前人嘗試引入了 MVC,也只是改成把所有程式都塞在 Controller 而已,其絕望程度可見一斑。

這時候隔壁課的老盤調過來接刀,一看不得了,便決定先對這屎山整頓一番。他大喝一聲,那些靠近使用者的便上浮起來化作了天,親近資料庫的便沉澱下去變成了地,而所有的商業邏輯就連接著兩者,支撐起了整個專案。這也就是分層架構的由來。

三層式架構

分層架構是運用最為廣泛的架構模式,幾乎每個軟體系統都需要通過層(Layer)來隔離不同的關注點(Concern Point),以此應對不同需求的變化,使得這種變化可以獨立進行;此外,分層架構模式還是隔離業務複雜度與技術複雜度的利器。 -- Ray’s Notes

一般來說,最常見的分層架構就是三層式架構了。

三層式架構顧名思義就是把應用程式分成三層,通常會分成「展示層、商業邏輯層、資料存取層」。

分層架構01

……

閱讀全文


菜雞抓蟲: 使用 FromUri 的複雜型別在有傳遞 QueryString 的情況下會先建立再賦值

Image

事發緣由

在 .net Framework 4.6.2 MVC 的 ApiController 中,某個查詢資料列表的方法除了提供查詢條件的參數以外,還有提供選擇性的分頁參數。也就是像這樣子:

[HttpGet]
public IEnumerable<Boo> GetBoos(
    [FromUri] SearchBooParameter parameter,
    [FromUri] PagingParameter paging = null)
{
    // 呼叫 Service 查資料...
}

由於需要調整該功能的預設排序,改為由大到小,又不想背負更改大量共用的 PagingParameter 去影響到其他使用到的地方,決定在 Controller 這裡簡單用預測值加上判斷處理一下就好

相信著「若使用者沒有傳遞 paging 相關的參數,應該就會是給定的預設值 null 吧!」的我,用了 if (paging is null) 進行判斷:若是 null 的情況就將其中用來標示排序方向的成員 isDesc 設定為 true,開開心心交差。

[HttpGet]
public IEnumerable<Boo> GetBoos(
    [FromUri] SearchBooParameter parameter,
    [FromUri] PagingParameter paging = null)
{
    if (paging is null)
    {
        paging = new PagingParameter();
        paging.isDesc = true; // 預設由大到小
    }
    // 呼叫 Service 查資料...
}

但實際使用之後發現:即使只有傳入查詢條件參數、未傳遞 paging 時,資料仍然由小到大顯示,且 paging.isDesc 竟然是 false,並未被更改到。也就是說,即使未傳遞 paging,它也並不是 null!

實測之後發現:若在呼叫該 API 的時候,給定一個完全無關的參數,例如 ?a=1,則 paging 還是會被建立一個實體出來,並無視 = null 這個預設值。因此就導致了非預期(=跟我想的不一樣啊!)的行為。

這邊直接先講結論:如果有傳遞 QueryString 的任何參數時,不管這些參數跟指定的類別有沒有關係,放在 [FromUri] 的複雜型別都會先建立出實體,再嘗試和 QueryString 的內容進行比對與設值

設定在 [FromUri] 的複雜型別身上的預設值,像是 [FromUri] PagingParameter paging = null 只有完全沒給任何 QueryString 的時候才會吃到。(不過因為預設值只能是常數的關係,基本上就是指 defualt 的 null)

因此如果遇到要給定預設值的場合,還是得乖乖地針對型別中的成員做設定比較保險,例如 bool isDesc { get; set; } = true。另外,因為完全沒給 QueryString 的時候還是會是 null,故該有的參數檢查仍然不能漏了。

……

閱讀全文


菜雞抓蟲: Url 變得怪怪的?你可能是零寬空格(ZWSP)的受害者!

這週遇到個想不到的坑,特別來記錄一下。故事是這樣的--

在需要呼叫其他 API 服務時,發生了以下怪事:

  • 打某支查詢 API,突然查不到任何東西,或是跳出參數錯誤
  • 有些需要用參數組成 URL 的 API 跑出 Not Found
    • 第一組資料呼叫成功,第二組突然路徑錯誤
  • 寫入的時候,資料莫名其妙多了個 ?
    • 例如原先的資料是 ABC,不知怎地變成了 ABC?

由於這些操作都涉及到同一個參數,直覺上就是我們這邊給的參數出了點問題,馬上進入找犯人的環節。直接中斷點標記下去,反覆觀察該字串,但它就是一個普通的字串 "ABC",完全看不出什麼端倪。

正要覺得參數沒有問題的時候,赫然發現組出來的 Url 相當不對勁:在該參數的後方,多出了 %E2%80%8B 這串神秘東西!

當下我驚呆了,我們傳出去的 Url 裡,並不是預想的 /api/product/ABC,而是 /api/product/ABC%e2%80%8b!真是赤裸裸的背叛!這串鬼東西到底是什麼來頭?!

……

閱讀全文


菜雞新訓記 (4): 使用 Swagger 來自動產生可互動的 API 文件吧

img

這是俺整理公司新訓內容的第四篇文章,目標是簡單地使用 Swagger 工具來自動產生可互動的 API 文件

API 文件與 Swagger

上一篇 我們建立了一個有簡單的 CRUD 的 Web API 服務,這篇我們就接續著 API 服務往下看吧!

之前我們介紹 API 的時候有提過:API 是為了讓兩個服務之間可以溝通、互動所產生的接口。而所有的溝通要有效,都一定要先有共識,隨著溝通的人數越來越多,或是內容的理解要越來越細,就會用文件或契約的方式來達成共識。

回到我們的 API 服務開發來說,就是你除了把服務生出來了,可以跑了以外,還有一個重要的點是:必須讓所有的使用者(包含幾個月後的你自己)知道怎麼使用這組 API 服務

也就來說,就是要寫 API 規格文件 啦!

……

閱讀全文


菜雞新訓記 (3): 使用 Dapper 來連線到資料庫 CRUD 吧

Image

這是俺整理公司新訓內容的第三篇文章,目標是在 .NET Core 簡單地使用 Dapper 連線到資料庫並完成 CRUD 的功能

接續 上一篇 的進度,我們接著要來連線到資料庫中完成我們的 Web Api 的 CRUD 範例。因為從新訓時期到現在工作團隊作業上主要都是使用 Dapper 來做連線資料庫的工作,這邊就直接用 Dapper 來推進吧!

Dapper 有多好用呢?它輕量、它簡單、它快速。總之先把大神們的介紹文直接拿來鎮樓:

那麼按照慣例,我們先來 吹捧今天的主角 說明一點簡單的前因後果吧。想直接實作的朋友,可以跳到正式開工的小節呦。

……

閱讀全文


菜雞新訓記 (2): 認識 Api & 使用 .net Core 來建立簡單的 Web Api 服務吧

Image

這是俺整理公司新訓內容的第二篇文章,目標是對 Api, Restful Api, HTTP 等相關的知識點做個筆記,並用 .net Core 建立一個簡易的 Web Api 專案

前言、基本觀念

我們在 上一篇 記錄了新訓第一天的 Git 操作筆記。接著在這篇,我們終於要進入 .net Core 啦!

目前的規劃是先從建立一個可以使用的、最簡單版本的 Web Api 服務開始,再將各個工具擴增進來。所以後續的文章應該都會以這篇的簡易 API 為基底繼續延伸下去(如果順利的話啦)

這篇文章的前半段會用來記錄一些使用或開發 API 常用到的相關知識,如果對 HTTP 的部分已經有點頭緒,或是迫不及待想直接動手用 .net Core 開 Api 服務的朋友們,可以直接跳到 正式開工 的部份。那麼,我們開始吧~


什麼是 API

我們在物件導向的 介面 時有稍微聊過所謂介面(Interface)的概念:「在兩個系統,或是兩個分層之間要介接的時候,只需要提供我這個功能的接口/介面給對方,就能讓對方知道如何使用」

API(Application Programming Interface)也是同樣的道理:

在不同的應用程式或服務(Application)之間,使用程式碼(Programming)的方式提供一組 介面(Interface),讓提供方和使用方可以藉由這組介面銜接起來。

API 最貼切的比喻就是我們在 封裝篇 也用過的販賣機:販賣機會提供不同飲料的按鈕,當我們選擇了其中一個按鈕按下、投了錢之後,對應的飲料就會掉下來。

對應回來就是:我們到了某個服務(販賣機),去拿我們想要的資料(飲料),所以呼叫了該服務的某支 API(按鈕)並且提供了一些該 API 要求的資料(投錢),最後 API 就會把我們想要的資料交給我們(飲料)

再用更實際的例子來說就像是:假設我們想要做一款可以查詢台北市的公車動態的 APP,於是我們到了提供公車動態的服務 MOTC Transport API v2 去找我們想要的 API,過程中我們可能需要告訴服務我們要查的是台北市,最後服務就會將公車動態的資料交給我們。

關於 API 的部份,推薦可以先閱讀過 Huli 大大的這兩篇,將基本觀念說明的相當好懂且透徹:

另外,也推一下我在 CodingBar 看到的這篇 API 到底是什麼? 用白話文帶你認識 和它所引用的影片:

……

閱讀全文