定义服务契约

``

概念阐述

服务契约,指基于OpenAPI规范的微服务接口契约,是服务端与消费端对于接口的定义。java chassis提供了两种方式定义契约:code first和contract first。

  • code first producer使用Jax-RS或SpringMVC的RESTful annotation声明接口的输入、输出参数,或者再配合OpenAPI的annotation,增加人类可读的信息,比如样例代码、文本描述等等;ServiceComb引擎启动时,根据这些annotation生成契约描述,并自动上传到服务中心。producer也可以使用透明RPC方式开发,但是因为没有任何RESTful的annotation指导如何生成契约,所以此时自动生成的契约非常的不RESTful化,不建议使用。consumer使用透明RPC或RestTemplate进行调用。code first的开发模式下,开发人员,不必手写契约。

  • contract first 此场景下,不使用框架自动生成的契约,而是直接使用开发人员提供的契约文件,这需要由开发人员保证契约与代码的一致性。

场景描述

服务契约用于服务端和消费端的解耦,服务端围绕契约进行服务的实现,消费端根据契约进行服务的调用,可支持服务端和消费端采用不同的编程语言实现。

说明:服务提供者在启动时会将接口契约注册到服务中心,可供服务消费者下载使用。接口契约是微服务-版本级别的信息,当多个微服务实例启动时,有一个实例将契约注册到服务中心后,服务中心就不会再用后来者注册的契约信息覆盖已有的契约。因此,仅修改服务提供者的接口信息不会让服务中心存储的契约发生变化,对于服务消费者而言,获取到的接口信息依然是旧的。若要更新服务中心中的接口契约,可以选择升级微服务版本号,或者删除已有的微服务信息(后者不建议在生产环境使用)。

配置说明

ServiceComb使用yaml文件格式定义服务契约,推荐使用Swagger Editor工具来编写契约,可检查语法格式及自动生成API文档。详细的契约文件格式请参考OpenAPI官方文档

契约文件放置在"resources/microservices"或者"resources/application"目录下,目录结构如下所示。

  1. resources
  2. - microservices
  3. - serviceName #微服务名
  4. - schemaId.yaml #schema接口的契约
  5. - applications
  6. - appId #应用ID
  7. - serviceName #微服务名
  8. - schemaId.yaml #schema接口的契约
注意:- ServiceComb的Swagger契约文件应当使用UTF-8字符集保存。如果当用户使用其他字符集保存契约文件,且文件中包含中文字符时,可能会导致未知错误。

示例代码

resources/microservices目录和resources/application目录下的schemaId.yaml文件内容示例如下。文件中的接口定义需要与服务的实际接口相符。

  1. swagger: '2.0'
  2. info:
  3. title: hello
  4. version: 1.0.0
  5. x-java-interface: org.apache.servicecomb.samples.common.schema.Hello
  6. basePath: /springmvchello
  7. produces:
  8. - application/json
  9. paths:
  10. /sayhi:
  11. post:
  12. operationId: sayHi
  13. parameters:
  14. - name: name
  15. in: query
  16. required: true
  17. type: string
  18. responses:
  19. 200:
  20. description: 正确返回
  21. schema:
  22. type: string
  23. default:
  24. description: 默认返回
  25. schema:
  26. type: string
  27. /sayhello:
  28. post:
  29. operationId: sayHello
  30. parameters:
  31. - name: person
  32. in: body
  33. required: true
  34. schema:
  35. $ref: "#/definitions/Person"
  36. responses:
  37. 200:
  38. description: 正确返回
  39. schema:
  40. type: string
  41. default:
  42. description: 默认返回
  43. schema:
  44. type: string
  45. definitions:
  46. Person:
  47. type: "object"
  48. properties:
  49. name:
  50. type: "string"
  51. description: "person name"
  52. xml:
  53. name: "Person"

注意

  • ServiceComb中的契约,建议basePath不要包含web container的web root,以及servlet的url pattern。

因为ServiceComb支持部署解耦,既可以脱离servlet container独立部署,也可使用war的方式部署到servlet container中,还可以使用embedded servlet container的方式运行。只要base path不包含web root以及url pattern,则部署方式修改导致的实际url变更,ServiceComb consumer业务代码并不需要感知,框架会自动适配。

  • info.x-java-interface需要标明具体的接口路径,根据项目实际情况而定。
  • SchemaId中可以包含"."字符,但不推荐这样命名。这是由于ServiceComb使用的配置文件是yaml格式的,"."符号用于分割配置项名称,如果SchemaId中也包含了"."可能会导致一些支持契约级别的配置无法正确被识别。
  • OperationId的命名中不可包含"."字符。