本文分享自華爲雲社區《Java Chassis 3技術解密:契約優先(API First)開發》,作者: liubao68。
契約優先(API First)開發是指應用程序開發過程中,將API設計作爲第一優先級的任務。契約優先開發隨着Web Services概念的發展而不斷得到重視,特別是微服務架構出現以後,API設計成爲影響功能開放、性能優化等問題的關鍵因素。常見的契約優先開發框架和模式有如下幾種:
- Web Services技術可以由設計人員先編寫WSDL描述WEB服務內容,然後結合工具生成代碼。WSDL可以進行分發,不同的語言都可以結合WSDL生成客戶端。
- gRPC技術可以由設計人員先編寫IDL描述RPC服務內容,然後結合工具生成代碼。gRPC主要解決服務內部之間的調用。
- Spring Boot允許開發人員利用swagger工具,先編寫Open API接口,然後通過工具生成RESTFul的服務端代碼。
這些技術都要求設計人員掌握一種語言無關的描述語言(WSDL、IDL、Swagger等),並且通過工具生成具體語言的代碼。它們支持的應用場景也有所差異,Web Service適合對外的WEB服務,gRPC適合對內的RPC服務。Java Chassis契約優先開發具備下面的幾個改進:
- 允許直接使用Java語言定義服務接口,不需要設計者掌握新的描述語言。
- 同時定義Web服務接口和內部RPC接口。
和Spring Boot一樣, Java Chassis的語言無關性描述語言仍然是Open API,通過Open API,可以滿足跨語言和服務分發的要求。
契約優先開發的過程
契約優先開發可以涵蓋設計、開發、測試、部署、運維等軟件開發的全流程,通過契約可以實現不同環節的並行工作,從而提高開發效率。 一個簡單的契約開發過程如下:
下面通過代碼簡單展示通過Java語義定義契約,並實現提供者和消費者的過程。
- 定義服務契約
@RequestMapping(path = "/provider") public interface ProviderService { @GetMapping("/sayHello") String sayHello(@RequestParam("name") String name); }
- 定義提供者
@RestSchema(schemaId = "ProviderController", schemaInterface = ProviderService.class) public class ProviderController implements ProviderService { @Override public String sayHello(String name) { return "Hello " + name; } }
- 定義消費者
@Configuration public class ProviderServiceConfiguration { @Bean public ProviderService providerService() { return Invoker.createProxy("provider", "ProviderController", ProviderService.class); } }
使用RPC方式訪問提供者。
@RestSchema(schemaId = "ConsumerController", schemaInterface = ConsumerService.class) public class ConsumerController implements ConsumerService { private ProviderService providerService; @Autowired public void setProviderService(ProviderService providerService) { this.providerService = providerService; } @Override public String sayHello(String name) { return providerService.sayHello(name); } }
- 服務分發和Web服務訪問
提供者的服務定義會生成如下Open API信息
openapi: 3.0.1 info: title: swagger definition for org.apache.servicecomb.samples.api.ProviderService version: 1.0.0 servers: - url: /provider paths: /sayHello: get: operationId: sayHello parameters: - name: name in: query required: true schema: type: string responses: "200": description: response of 200 content: application/json: schema: type: string application/protobuf: schema: type: string text/plain: schema: type: string components: {}
這個信息可以用於WEB服務訪問,比如上面的信息可以使用
GET /providers/sayHello?name=World
的HTTP請求來訪問。 對於其他框架或者語言,也可以使用Open API生成對應的代碼來訪問。
服務治理
服務治理被設計爲獨立於開發過程,結合Open API和服務治理規則描述語言,能夠對API進行服務治理配置。
servicecomb: matchGroup: helloOperation: | matches: - apiPath: prefix: "/provider/sayHello" rateLimiting: ## 限流器每10毫秒允許通過100個請求,如果一個請求超過1000毫秒沒有獲取到 ## 許可,將被拒絕 helloOperation: | rate: 100 limitRefreshPeriod: 10 timeoutDuration: 1000
上述規則對API接口進行限流控制。
契約優先開發的其他方面
測試方面,可以通過契約生成自動化測試代碼,以覆蓋API的測試。 部署實施方面,可以將Open API信息導入網關,實現API能力開放、認證鑑權、計費等。 此外,契約還可以用於文檔生成、應用監控統計等各個方面。
總結
Java Chassis基於JAVA語言的接口定義,可以同時滿足Native語言和平臺無關描述語言兩種情況的SDK分發,並且不需要使用工具生成額外的運行代碼,給外部服務開發和內部服務開發提供了統一一致的開發體驗。 契約優先開發是面向服務化/微服務化非常高效的過程方法,Java Chassis給支持契約優先開發提供了很好的工具支持。