點先可以提升寫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, 正是上面例子的重點問題

可以學下 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。

TOP

AWS Lambda + API Gateway

TOP

你個咩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到...希望你平時唔係咁做...

TOP

本帖最後由 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

TOP

太大分做microservice 就ok。

正常一個api endpoint 唔會有噉多api,有太多應該係設計問題。

TOP

本帖最後由 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 方法去解決

TOP

TOP

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個定一個?

TOP