不知所措:您是否真的需要为您的API提供客户端库?
RESTful Web服務和API的優點在于,任何使用HTTP協議的使用者都可以理解和使用它。 但是,同樣的難題一遍又一遍地彈出:您是否應該將Web APis與客戶端庫一起使用? 如果是,您應該支持哪些語言或/和框架?
通常這并不是一個容易回答的問題。 因此,讓我們退后一步,想一想總體思路:客戶端庫可以為消費者帶來什么價值?
也許有人會說降低采用的門檻。 確實,特別是在強類型語言的情況下,從您喜歡的IDE探索API合同(請語法突出顯示和自動完成!)非常方便。 但是總的來說, RESTful Web API非常簡單,一開始就可以使用,并且好的文檔當然在這里會更有價值。
其他人可能說,保護消費者避免使用多個API版本或粗糙邊緣是件好事。 也是有道理的,但我認為這只是掩蓋了有關Web API的設計和隨著時間的發展而存在的缺陷。
總而言之,無論您決定捆綁多少個客戶端,任何通用的HTTP使用者( curl , HttpClient , RestTemplate ,您都可以命名)仍然可以訪問這些API。 做出選擇是很棒的,但是維護費用可能會很高。 我們可以做得更好嗎? 正如您可能已經猜到的,因此在本帖子中,我們當然有很多選擇。
成功的關鍵要素是使用OpenAPI v3.0或什至其前身Swagger / OpenAPI 2.0 (或RAML , API Blueprint并沒有多大關系)來維護RESTful Web API的準確規范。 在使用OpenAPI / Swagger的情況下,該工具為王:可以使用Swagger Codegen (一種模板驅動的引擎)以多種不同的語言生成API客戶端(甚至是服務器存根),這就是我們要討論的內容在這篇文章中。
為了簡化操作,我們將實現上一篇文章中構建的人員管理Web API的使用者。 首先,我們需要得到它開始的OpenAPI V3.0規范的YAML (或JSON )格式。
java -jar server-openapi/target/server-openapi-0.0.1-SNAPSHOT.jar然后:
wget http://localhost:8080/api/openapi.yaml太棒了,實際上完成了一半的工作。 現在,讓我們讓Swagger Codegen帶頭。 為了不使問題復雜化,我們假設使用者也是Java應用程序,因此我們可以毫無困難地理解其機制(但是Java只是其中一種選擇, 受支持的語言和框架的列表令人驚訝)。
在本文中,我們將使用OpenFeign ,這是最高級的Java HTTP客戶端綁定程序之一。 它不僅非常簡單易用,而且還提供了許多集成,我們將從中很快受益。
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>9.7.0</version> </dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-jackson</artifactId><version>9.7.0</version> </dependency>Swagger Codegen可以作為獨立的應用程序從命令行運行,也可以作為Apache Maven插件運行(后者是我們要使用的插件)。
<plugin><groupId>io.swagger</groupId><artifactId>swagger-codegen-maven-plugin</artifactId><version>3.0.0-rc1</version><executions><execution><goals><goal>generate</goal></goals><configuration><inputSpec>/contract/openapi.yaml</inputSpec><apiPackage>com.example.people.api</apiPackage><language>java</language><library>feign</library><modelPackage>com.example.people.model</modelPackage><generateApiDocumentation>false</generateApiDocumentation><generateSupportingFiles>false</generateSupportingFiles><generateApiTests>false</generateApiTests><generateApiDocs>false</generateApiDocs><addCompileSourceRoot>true</addCompileSourceRoot><configOptions><sourceFolder>/</sourceFolder><java8>true</java8><dateLibrary>java8</dateLibrary><useTags>true</useTags></configOptions></configuration></execution></executions> </plugin>如果某些選項不是很清楚,那么Swagger Codegen會提供很好的文檔來進行說明。 要注意的重要方面是language和library ,它們分別設置為java和feign 。 需要注意的一件事是, OpenAPI v3.0規范的支持大部分已經完成,但是您仍然可能會遇到一些問題(如您所注意到的,版本是3.0.0-rc1 )。
構建完成后,您將得到的是純樸的Java接口PeopleApi (帶有OpenFeign批注),它是人員管理Web API規范(來自/contract/openapi.yaml )的直接投影。 請注意,所有模型類也會生成。
@javax.annotation.Generated(value = "io.swagger.codegen.languages.java.JavaClientCodegen",date = "2018-06-17T14:04:23.031Z[Etc/UTC]" ) public interface PeopleApi extends ApiClient.Api {@RequestLine("POST /api/people")@Headers({"Content-Type: application/json", "Accept: application/json"})Person addPerson(Person body);@RequestLine("DELETE /api/people/{email}")@Headers({"Content-Type: application/json"})void deletePerson(@Param("email") String email);@RequestLine("GET /api/people/{email}")@Headers({"Accept: application/json"})Person findPerson(@Param("email") String email);@RequestLine("GET /api/people")@Headers({"Accept: application/json"})List<Person> getPeople(); }讓我們將其與具有相同規范的Swagger UI解釋進行比較,可從http:// localhost:8080 / api / api-docs?url = / api / openapi.json獲得 :
乍一看似乎正確,但我們最好確保一切按預期進行。 一旦有了帶有OpenFeign注釋的接口,就可以使用Feign構建器家族將其啟用 (在本例中,通過代理實現),例如:
final PeopleApi api = Feign.builder().client(new OkHttpClient()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).logLevel(Logger.Level.HEADERS).options(new Request.Options(1000, 2000)).target(PeopleApi.class, "http://localhost:8080/");偉大,流利的建筑風格的巖石。 假設我們的人員管理Web API服務器已啟動并正在運行(默認情況下,它將在http:// localhost:8080 /上可用):
java -jar server-openapi/target/server-openapi-0.0.1-SNAPSHOT.jar我們可以通過調用新構建的PeopleApi實例方法來與之通信,如下面的代碼片段所示:
final Person person = api.addPerson(new Person().email("a@b.com").firstName("John").lastName("Smith"));真的很酷,如果我們將其倒回一點,我們實際上什么也沒做。 僅提供Web API規范,一切都是免費提供給我們的! 但是,讓我們不要在這里停下來,提醒自己,使用Java接口不會消除我們正在處理遠程系統的現實。 毫無疑問,事情遲早會在這里失敗。
不久前,我們了解了斷路器及其在分布式系統中正確應用時的實用性。 以某種方式將這個功能引入我們基于OpenFeign的客戶端真的很棒。 請歡迎該家族的另一個成員HystrixFeign builder與Hytrix庫無縫集成:
final PeopleApi api = HystrixFeign.builder().client(new OkHttpClient()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).logLevel(Logger.Level.HEADERS).options(new Request.Options(1000, 2000)).target(PeopleApi.class, "http://localhost:8080/");我們唯一需要做的就是將這兩個依賴項添加到使用者的pom.xml文件中(嚴格來說,如果您不介意使用舊版本,則不需要hystrix-core )。
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-hystrix</artifactId><version>9.7.0</version> </dependency><dependency><groupId>com.netflix.hystrix</groupId><artifactId>hystrix-core</artifactId><version>1.5.12</version> </dependency>可以說,這是集成多么容易和直接的最好的例子之一。 但這還不是故事的結局。 分布式系統中的可觀察性從來沒有像現在這樣重要,正如我們不久前所了解的那樣 ,分布式跟蹤在幫助我們解決這一問題上非常有用。 再說一次, OpenFeign開箱即用地支持它,讓我們來看一下。
OpenFeign與兼容OpenTracing的跟蹤器完全集成。 Jaeger跟蹤器就是其中之一,它具有非常好的Web UI前端,可以探索跟蹤和依賴項。 讓我們先運行它,幸運的是它是完全Docker化的。
docker run -d -e \COLLECTOR_ZIPKIN_HTTP_PORT=9411 \-p 5775:5775/udp \-p 6831:6831/udp \-p 6832:6832/udp \-p 5778:5778 \-p 16686:16686 \-p 14268:14268 \-p 9411:9411 \jaegertracing/all-in-one:latest為了使OpenFeign客戶端了解OpenTracing功能,還必須引入幾個其他依賴項。
<dependency><groupId>io.github.openfeign.opentracing</groupId><artifactId>feign-opentracing</artifactId><version>0.1.0</version> </dependency><dependency><groupId>io.jaegertracing</groupId><artifactId>jaeger-core</artifactId><version>0.29.0</version> </dependency>從Feign構建器的角度來看,唯一的變化(除了引入tracer實例之外)是將客戶端包裝到TracingClient中 ,如下面的代碼片段所示:
final Tracer tracer = new Configuration("consumer-openapi").withSampler(new SamplerConfiguration().withType(ConstSampler.TYPE).withParam(new Float(1.0f))).withReporter(new ReporterConfiguration().withSender(new SenderConfiguration().withEndpoint("http://localhost:14268/api/traces"))).getTracer();final PeopleApi api = Feign.builder().client(new TracingClient(new OkHttpClient(), tracer)).encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).logLevel(Logger.Level.HEADERS).options(new Request.Options(1000, 2000)).target(PeopleApi.class, "http://localhost:8080/");在服務器端,我們還需要與OpenTracing集成。 Apache CXF 對它提供了一流的支持 ,捆綁到cxf-integration-tracing-opentracing模塊中。 讓我們將其作為依賴項包括在內,這一次是服務器的pom.xml 。
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-integration-tracing-opentracing</artifactId><version>3.2.4</version> </dependency>根據配置應用程序的方式,應該有一個可用的跟蹤程序實例,例如,稍后應將其傳遞給OpenTracingFeature 。
// Create tracer final Tracer tracer = new Configuration("server-openapi", new SamplerConfiguration(ConstSampler.TYPE, 1),new ReporterConfiguration(new HttpSender("http://localhost:14268/api/traces"))).getTracer();// Include OpenTracingFeature feature final JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean(); factory.setProvider(new OpenTracingFeature(tracer())); ... factory.create()從現在開始,通過生成的OpenFeign客戶端對任何人員管理API端點的調用將完全可在Jaeger Web UI中找到,該Web UI可從http:// localhost:16686 / search獲取 (假設Docker主機為localhost )。
我們的場景非常簡單,但請想象一下實際的應用程序,其中單個請求在系統中傳輸時,可能會發生數十個外部服務調用。 沒有適當的分布式跟蹤,每個問題都有機會變成一個謎。
附帶說明一下,如果您更靠近圖片中的痕跡,則可能會注意到服務器和使用者使用了不同版本的Jaeger API。 這不是錯誤,因為最新發布的Apache CXF版本使用的是較舊的OpenTracing API版本(因此,也使用了較舊的Jaeger客戶端API),但這不會阻止事情按預期進行。
這樣,就該總結了。 希望在RESTful Web服務和API的世界中基于合同(甚至更好,首先合同)開發的好處變得越來越明顯:智能客戶端的生成, 消費者驅動的合同測試 ,可發現性和豐富的文檔越來越多只是一些提及。 請利用它!
完整的項目資源可在Github上找到 。
翻譯自: https://www.javacodegeeks.com/2018/06/provide-client-libraries-apis.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的不知所措:您是否真的需要为您的API提供客户端库?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nba2k17安卓版中文版破解版(nba
- 下一篇: 笔记本电脑触摸板如何打开和关闭电脑开关如