Board logo

標題: 點先可以提升寫web api的能力? [打印本頁]

作者: 3ldk    時間: 2017-8-23 20:04     標題: 點先可以提升寫web api的能力?

本帖最後由 3ldk 於 2017-8-23 20:05 編輯

任何方法都得, 可以係用某個tools, 某種技術, 某種技巧, 甚至用某種標準流程都可以

下面直接用code講出而家寫api會有咩問題

一個好簡單既例子, 睇落好似跟足standard, 好標準既寫法, 但其實當中有不少問題, 請留意comment

Server:
  1. // 問題1: API條path, 當API越黎越多, 越黎越長, 或者越黎越複雜, 要開一個新API, 又唔知有無同之前撞,
  2. // 特別係如果用framework, d framework好中意將所有route同全個program寫晒係同一個index.php入面, 要查返之前寫落的API特別困難
  3. // 就算假設有好好既documentation, 將所有api寫晒落一個excel入面, 一行一個, 當api去到幾百個甚至過千, 一樣好難睇
  4. // 而且只要多過一個copy(excel一個, index.php一個), 就好容易出現唔同步, 花功夫去maintain依樣野, 又係一個成本
  5. Route::get('product', function () {  //get product list

  6.         $products=array();
  7.         for($i=1; $i<10; $++){
  8.                 //問題2: 用黎交換data的class, client side已經整左一個, 但server又要再寫一次, 容易出現不一致, 例如依度的productName, 就同client的name不同了, 一但出現依個問題, 又要花時間debug
  9.                 //唔只咁, 係server係要每個route都寫一次個class, 就係下面條route, 正正係一個例子, 依度寫左係productName, 但下面就叫pName, 咁又要debug一餐
  10.                 $product=new stdClass();
  11.                 $product->id=$i;
  12.                 $product->productName='name'.$i;
  13.                 array_push($products, $product);
  14.         }
  15.     return json_encode($products);
  16. });
  17. Route::post('product', function () {  //all a product

  18.         $product=new stdClass();
  19.         $product->pid=10;
  20.         $product->pName='name10';
  21.         //... save prodcut to DB
  22.     return json_encode($product);
  23. });
  24. Route::patch('product/{id}', function ($id) {  //update a product

  25.         //...
  26. });
  27. Route::delete('product/{id}', function ($id) {  //delete a product

  28.         //...
  29. });
複製代碼
Client:
  1. public class Product {
  2.     public int id;
  3.     public String name;
  4. }

  5. //問題3: route既問題同server類似, 但更嚴重, server都仲話一個index.php寫晒所有route, 但client side因為係call既一方, call既route分散晒係不同的class, 仲難管理
  6. //不過, 當然最大問題都係在於, server定義左一次, client又定義一次, 極容易出現不一致, 雖然依種bug係容易發現, 但亦同時經常出現, 特別係route一多
  7. //正是因為出現得太多, 加加埋埋都花唔少時間
  8. StringRequest stringRequest = new StringRequest(Request.Method.GET, "xxxxx/product",
  9.         new Response.Listener<String>() {
  10.                 @Override
  11.                 public void onResponse(String response) {
  12.                         Gson gson=new Gson();
  13.                         Product[] p=gson.fromJson(response,Product.class);
  14.                 }
  15.         },
  16.         new Response.ErrorListener() {
  17.                 @Override
  18.                 public void onErrorResponse(VolleyError error) {
  19.                         Log.v("VolleyError", error.getMessage());
  20.                 }
  21.         });
  22. StringRequest stringRequest = new StringRequest(Request.Method.POST, "xxxxx/product", //省略
  23. StringRequest stringRequest = new StringRequest(Request.Method.PATCH, "xxxxx/product", //省略
  24. StringRequest stringRequest = new StringRequest(Request.Method.DELETE, "xxxxx/product", //省略
複製代碼
問題講住咁多, 我諗暫時最低級, 最不用技術既解決方法, 就係盡量做好d documentation
但咁未必係好好既解決方法, 因為做多份document出黎, 即係多份copy, 亦即係更容易出錯, 而且多過一份copy, 正是上面例子的重點問題
作者: justlazy    時間: 2017-8-23 20:57

可以學下 RESTful API design。用 resources oriented design,加埋 API versioning,server side 唔會話撞。Client side 方面,由於係 resources oriented,request endpoint 係可以 generate 出嚟。

至於 server side 啲 route 點放,呢個完全係 architecture 嘅問題。有人鐘意有個 route file 放曬所有 route,有人會 delegate 啲 subroute 去唔同嘅 module。小弟自己就選擇 convention over configuration,可以參考 Ember.js 嘅 routing 設計。

apigee 有好多好嘅 materials。
作者: hermanho    時間: 2017-8-24 20:55

AWS Lambda + API Gateway
作者: 梁炳    時間: 2017-8-24 22:13

你個咩WebApp....API幾百個甚至過千?
首先點都會有Pattern, 唔會續條CRUD hard-code出來吧
用適合你個case既方法去define 唔同modules,然後產生相關既route就可以
例如product, category, brand, customer各有CRUD,咁寫一次就ok la

就算你個App真係非常複雜,寫個facebook出來
通常scale up到咁上下,就會有分拆做micro service既需要
咁都唔會寫哂係同一隻webapp到吧
API多到人manage唔到既機會好細

Server 點解會"每個route都寫一次個class"? 點解你唔define一個Model出來,睇唔明

至於Client同Server一至性,你應該寫一個API client的repo出來,由server side既人員maintain
而Client-side既同事只code on API client的API,咁就一定無問題
就算係得你自己做,都值得咁做

無論server side同client side,都總有方法集中一個點去define野,看閣下功力

p.s. 見到你d controller logic寫係route到...希望你平時唔係咁做...
作者: hihihi123hk    時間: 2017-8-25 09:52

本帖最後由 hihihi123hk 於 2017-8-25 09:54 編輯

簡單而言(問題1)
寫 Php 但係又想好 Maintain

一係正如你所講海量 Doc
一係100% Test coverage

做唔到嘅/覺得唔值得做嘅,建議用其它 Type-safe Language 做 API Server。大部份Framework 都可以於 Compile Time 解決到 問題1


問題2,3 可以用 Google Protocol buffer 解決

via HKEPC Ionic Reader v1.7.1 - iPhone
作者: tsangwailam    時間: 2017-8-25 10:12

太大分做microservice 就ok。

正常一個api endpoint 唔會有噉多api,有太多應該係設計問題。
作者: hihihi123hk    時間: 2017-8-25 10:45

本帖最後由 hihihi123hk 於 2017-8-25 10:47 編輯

回覆 6# tsangwailam


補充番先,呢個年代要有效咁活用 Microservice 都要學好多野基本野,至少 Docker, Git, Docker Swarm / Kubernetes。個人認為因為 Learning Curve 都算高,所以香港咁少人用(部份人都好怕難嘅野,未領略到佢嘅好就已經 Ban)

然後要運到到上述「基本野」嘅威力, 就要做埋 CI Server  (可以玩下 GitLab CI) , 再做埋 CD (可以用 GitLab CI 做埋)

唔係嘅話就咁用 Microservice 只會更難 Maintain ,啲野會散收收, Deploy  Friction 又高,有違 Micro-service 原意

順帶一提,另類方案
1. 用 Google App Engine 去實行 Microservice
2. Monolithic , 但 Code base 用 Modular 方法去解決
作者: TritonHo    時間: 2017-8-25 13:34

回覆 1# 3ldk


請慢用:
https://github.com/TritonHo/slid ... 20Design-tw-2.1.pdf
作者: ~虎~    時間: 2017-8-26 02:27

1.
> 將所有route同全個program寫晒係同一個index.php入面
呢個完完全全係 Misuse

> 要開一個新API, 又唔知有無同之前撞
Unit test / TDD

> 而且只要多過一個copy(excel一個, index.php一個), 就好容易出現唔同步, 花功夫去maintain依樣野, 又係一個成本
您需要 Document generator

2 & 3.
第一步定好 Naming conventions...
樓上提到 ProtoBuf 都幫到手

BTW... 好奇咩 WebApp 有幾百個 API
C/R/U/D 當4個定一個?





歡迎光臨 電腦領域 HKEPC Hardware (https://h1.hkepc.com/forum/) Powered by Discuz! 7.2