最小可行產品API的實現 - frankel

banq發表於2022-11-29

不寫一行程式碼的情況下,實現最小可行產品API:無需編寫 REST API程式碼,而是配置使用 PostgREST 元件。
PostgREST 是一個獨立的 Web 伺服器,可將您的 PostgreSQL 資料庫直接轉換為 RESTful API。資料庫中的結構約束和許可權決定了 API 端點和操作。

讓我們將它應用到一個簡單的用例中:

可以在GitHub 上找到完整的原始碼

PostgREST 的入門指南非常完整並且開箱即用。然而,我沒有找到任何現成的 Docker 映象,所以我建立了自己的:

FROM debian:bookworm-slim                                                   

ARG POSTGREST_VERSION=v10.1.1                                               
ARG POSTGREST_FILE=postgrest-$POSTGREST_VERSION-linux-static-x64.tar.xz     

RUN mkdir postgrest

WORKDIR postgrest

ADD https://github.com/PostgREST/postgrest/releases/download/$POSTGREST_VERSION/$POSTGREST_FILE \
    .                                                                       

RUN apt-get update && \
    apt-get install -y libpq-dev xz-utils && \
    tar xvf $POSTGREST_FILE && \
    rm $POSTGREST_FILE                  


docker-compose.yml

version: "3"
services:
  postgrest:
    build: ./postgrest                                   
    volumes:
      - ./postgrest/product.conf:/etc/product.conf:ro    
    ports:
      - "3000:3000"
    entrypoint: ["/postgrest/postgrest"]                 
    command: ["/etc/product.conf"]                       
    depends_on:
      - postgres
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: "root"
    volumes:
      - ./postgres:/docker-entrypoint-initdb.d:ro 


查詢資料表:

curl localhost:3000/product


增加修改功能
PostgREST 是構建 RESTful API 的快速方法。它的預設行為非常適合開發中的腳手架。當需要投入生產時,只要您採取預防措施,它也能很好地工作。PostgREST 是一個小巧的利器,專注於執行 API 到資料庫的對映。我們依靠像 Nginx 這樣的反向代理來提供額外的保護。

Apache APISIX替代nginx,我們將把它新增到我們的 Docker Compose 中:

version: "3"
services:
  apisix:
    image: apache/apisix:2.15.0-alpine                              
    volumes:
      - ./apisix/config.yml:/usr/local/apisix/conf/config.yaml:ro
    ports:
      - "9080:9080"
    restart: always
    depends_on:
      - etcd
      - postgrest
  etcd:
    image: bitnami/etcd:3.5.2                                       
    environment:
      ETCD_ENABLE_V2: "true"
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2397"
      ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2397"


我們將首先配置Apache APISIX來代理對postgrest的呼叫:

curl http://apisix:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: 123xyz' -X PUT -d '  
{
  "type": "roundrobin",
  "nodes": {
    "postgrest:3000": 1                                                              
  }
}'

curl http://apisix:9080/apisix/admin/routes/1 -H 'X-API-KEY: 123xyz' -X PUT -d '    
{
  "uri": "/*",
  "upstream_id": 1
}'


我們現在可以透過APISIX查詢端點:

curl localhost:9080/product


DDoS保護
我們還沒有新增任何東西,但我們已經準備好開始工作了。首先讓我們保護我們的API免受DDoS攻擊。Apache APISIX是圍繞一個外掛架構設計的。為了防止DDoS,我們將使用一個外掛。我們可以在建立特定路由時在其上設定外掛,也可以在每個路由上設定外掛;在後一種情況下,它是一個全域性規則。我們想預設保護每條路由:


curl http://apisix:9080/apisix/admin/global_rules/1 -H 'X-API-KEY: 123xyz' -X PUT -d '
{
  "plugins": {
    "limit-count": {                 
      "count": 1,                    
      "time_window": 5,              
      "rejected_code": 429           
    }
  }
}'

  • limit-count限制在一個時間視窗中的呼叫次數
  • 限制為每5秒1次呼叫;這是為了演示目的
  • 返回429太多請求;預設是503


每條路由的授權
PostgREST還在根部提供了一個Open API端點。因此,我們有兩個路由。/用於開放API規範,
/product用於產品。假設我們想禁止未經授權的人訪問我們的資料。普通使用者可以訪問產品,而管理使用者可以同時訪問Open API規格和產品。

APISIX提供了幾種認證方法。我們將使用最簡單的一種,即金鑰認證。key-auth需要一個特定的頭:該外掛對該值進行反向查詢,並找到其Key對應的消費者。

curl http://apisix:9080/apisix/admin/consumers -H 'X-API-KEY: 123xyz' -X PUT -d '    
{
  "username": "admin",                                                               
  "plugins": {
    "key-auth": {
      "key": "admin"                                                                 
    }
  }
}'

  • 建立一個新的消費者
  • 消費者的名字
  • 消費者的鍵值


我們對消費者使用者和關鍵使用者做同樣的工作。現在,我們可以建立一個專門的路由,並對其進行配置,以便只有來自管理員的請求可以透過。

curl http://apisix:9080/apisix/admin/routes -H 'X-API-KEY: 123xyz' -X POST -d ' 
{
  "uri": "/",
  "upstream_id": 1,
  "plugins": {
    "key-auth": {},                                                             
    "consumer-restriction": {                                                   
      "whitelist": [ "admin" ]                                                  
    }
  }
}'

  • 建立新路由
  • 使用key驗證和使用者限制外掛
  • 只有經過管理員身份驗證的請求才能呼叫路由


呼叫:

curl -H "apikey: admin" localhost:9080


監控
任何軟體系統的一個被低估的功能就是監控。一旦你在生產中部署了任何元件,你就必須監測其健康狀況。現在,有許多服務可以用來監控。我們將使用Prometheus,因為它是開源的、經過實戰檢驗的、廣泛的。為了顯示資料,我們將依靠Grafana,原因也是如此。讓我們把這些元件新增到Docker Compose檔案中。

docker-compose.yml

version: "3"
services:
  prometheus:
    image: prom/prometheus:v2.40.1                                    
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml    
    depends_on:
      - apisix
  grafana:
    image: grafana/grafana:8.5.15                                     
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning              
      - ./grafana/dashboards:/var/lib/grafana/dashboards              
      - ./grafana/config/grafana.ini:/etc/grafana/grafana.ini          
    ports:
      - "3001:3001"
    depends_on:
      - prometheus



一旦監控基礎設施到位,我們只需要指示APISIX以Prometheus期望的格式提供資料。我們可以透過配置和一個新的全域性規則來實現它。
config.yaml

plugin_attr:
  prometheus:
    export_addr:
      ip: "0.0.0.0"             
      port: 9091     


我們可以建立全域性規則:

curl http://apisix:9080/apisix/admin/global_rules/2 -H 'X-API-KEY: 123xyz' -X PUT -d '
{
  "plugins": {
    "prometheus": {}
  }
}'


結論
建立一個成熟的REST(ful)API是一項巨大的投資。人們可以透過PostgREST的CRUD API來快速測試一個簡單的API,暴露自己的資料庫。然而,這樣的架構並不適合在生產中使用。

為了解決這個問題,你需要在PostgREST前面設定一個façade,一個反向代理,或者更好的是一個API閘道器。Apache APISIX提供了廣泛的功能,從授權到監控。有了它,你可以以較低的成本快速驗證你的API需求。

錦上添花的是:當你驗證了需求後,你可以保留現有的立面,用你定製開發的API取代PostgREST。
 

相關文章