一、 什么是开放平台?

Apollo提供了一套的Http REST接口,使第三方应用能够自己管理配置。虽然Apollo系统本身提供了Portal来管理配置,但是在有些情景下,应用需要通过程序去管理配置。

二、 第三方应用接入Apollo开放平台

2.1 注册第三方应用

第三方应用负责人需要向Apollo管理员提供一些第三方应用基本信息。

基本信息如下:

  • 第三方应用的AppId、应用名、部门
  • 第三方应用负责人Apollo管理员在 http://{portal_address}/open/manage.html 创建第三方应用,创建之前最好先查询此AppId是否已经创建。创建成功之后会生成一个token,如下图所示:

开放平台管理

2.2 给已注册的第三方应用授权

第三方应用不应该能操作任何Namespace的配置,所以需要给token绑定可以操作的Namespace。Apollo管理员在 http://{portal_address}/open/manage.html 页面给token赋权。赋权之后,第三方应用就可以通过Apollo提供的Http REST接口来管理已授权的Namespace的配置了。

2.3 第三方应用调用Apollo Open API

2.3.1 调用Http REST接口

任何语言的第三方应用都可以调用Apollo的Open API,在调用接口时,需要设置注意以下两点:

  • Http Header中增加一个Authorization字段,字段值为申请的token
  • Http Header的Content-Type字段需要设置成application/json;charset=UTF-8
2.3.2 Java应用通过apollo-openapi调用Apollo Open API

从1.1.0版本开始,Apollo提供了apollo-openapi客户端,所以Java语言的第三方应用可以更方便地调用Apollo Open API。

首先引入apollo-openapi依赖:

  1. <dependency>
  2. <groupId>com.ctrip.framework.apollo</groupId>
  3. <artifactId>apollo-openapi</artifactId>
  4. <version>1.1.0</version>
  5. </dependency>

在程序中构造ApolloOpenApiClient

  1. String portalUrl = "http://localhost:8070"; // portal url
  2. String token = "e16e5cd903fd0c97a116c873b448544b9d086de9"; // 申请的token
  3. ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
  4. .withPortalUrl(portalUrl)
  5. .withToken(token)
  6. .build();

后续就可以通过ApolloOpenApiClient的接口直接操作Apollo Open API了,接口说明参见下面的Rest接口文档。

2.3.3 .Net core应用调用Apollo Open API

.Net core也提供了open api的客户端,详见https://github.com/ctripcorp/apollo.net/pull/77

三、 接口文档

3.1 URL路径参数说明

参数名参数说明
env所管理的配置环境
appId所管理的配置AppId
clusterName所管理的配置集群名, 一般情况下传入 default 即可。如果是特殊集群,传入相应集群的名称即可
namespaceName所管理的Namespace的名称,如果是非properties格式,需要加上后缀名,如sample.yml

3.2 API接口列表

3.2.1 获取App的环境,集群信息
  1. [
  2. {
  3. "env":"FAT",
  4. "clusters":[ //集群列表
  5. "default",
  6. "FAT381"
  7. ]
  8. },
  9. {
  10. "env":"UAT",
  11. "clusters":[
  12. "default"
  13. ]
  14. },
  15. {
  16. "env":"PRO",
  17. "clusters":[
  18. "default",
  19. "SHAOY",
  20. "SHAJQ"
  21. ]
  22. }
  23. ]
3.2.2 获取集群下所有Namespace信息接口
  1. [
  2. {
  3. "appId": "100003171",
  4. "clusterName": "default",
  5. "namespaceName": "application",
  6. "comment": "default app namespace",
  7. "format": "properties", //Namespace格式可能取值为:properties、xml、json、yml、yaml
  8. "isPublic": false, //是否为公共的Namespace
  9. "items": [ // Namespace下所有的配置集合
  10. {
  11. "key": "batch",
  12. "value": "100",
  13. "dataChangeCreatedBy": "song_s",
  14. "dataChangeLastModifiedBy": "song_s",
  15. "dataChangeCreatedTime": "2016-07-21T16:03:43.000+0800",
  16. "dataChangeLastModifiedTime": "2016-07-21T16:03:43.000+0800"
  17. }
  18. ],
  19. "dataChangeCreatedBy": "song_s",
  20. "dataChangeLastModifiedBy": "song_s",
  21. "dataChangeCreatedTime": "2016-07-20T14:05:58.000+0800",
  22. "dataChangeLastModifiedTime": "2016-07-20T14:05:58.000+0800"
  23. },
  24. {
  25. "appId": "100003171",
  26. "clusterName": "default",
  27. "namespaceName": "FX.apollo",
  28. "comment": "apollo public namespace",
  29. "format": "properties",
  30. "isPublic": true,
  31. "items": [
  32. {
  33. "key": "request.timeout",
  34. "value": "3000",
  35. "comment": "",
  36. "dataChangeCreatedBy": "song_s",
  37. "dataChangeLastModifiedBy": "song_s",
  38. "dataChangeCreatedTime": "2016-07-20T14:08:30.000+0800",
  39. "dataChangeLastModifiedTime": "2016-08-01T13:56:25.000+0800"
  40. },
  41. {
  42. "id": 1116,
  43. "key": "batch",
  44. "value": "3000",
  45. "comment": "",
  46. "dataChangeCreatedBy": "song_s",
  47. "dataChangeLastModifiedBy": "song_s",
  48. "dataChangeCreatedTime": "2016-07-28T15:13:42.000+0800",
  49. "dataChangeLastModifiedTime": "2016-08-01T13:51:00.000+0800"
  50. }
  51. ],
  52. "dataChangeCreatedBy": "song_s",
  53. "dataChangeLastModifiedBy": "song_s",
  54. "dataChangeCreatedTime": "2016-07-20T14:08:13.000+0800",
  55. "dataChangeLastModifiedTime": "2016-07-20T14:08:13.000+0800"
  56. }
  57. ]
3.2.3 获取某个Namespace信息接口
  1. {
  2. "appId": "100003171",
  3. "clusterName": "default",
  4. "namespaceName": "application",
  5. "comment": "default app namespace",
  6. "format": "properties", //Namespace格式可能取值为:properties、xml、json、yml、yaml
  7. "isPublic": false, //是否为公共的Namespace
  8. "items": [ // Namespace下所有的配置集合
  9. {
  10. "key": "batch",
  11. "value": "100",
  12. "dataChangeCreatedBy": "song_s",
  13. "dataChangeLastModifiedBy": "song_s",
  14. "dataChangeCreatedTime": "2016-07-21T16:03:43.000+0800",
  15. "dataChangeLastModifiedTime": "2016-07-21T16:03:43.000+0800"
  16. }
  17. ],
  18. "dataChangeCreatedBy": "song_s",
  19. "dataChangeLastModifiedBy": "song_s",
  20. "dataChangeCreatedTime": "2016-07-20T14:05:58.000+0800",
  21. "dataChangeLastModifiedTime": "2016-07-20T14:05:58.000+0800"
  22. }

3.2.4 创建Namespace

可以通过此接口创建Namespace,调用此接口需要授予第三方APP,APP级别的权限。

  • URLhttp://{portal_address} /openapi/v1/apps/{appId}/appnamespaces
  • Method : POST
  • Request Params :无
  • 请求内容(Request Body, JSON格式)

    参数名必选类型说明
    nametrueStringNamespace的名字
    appIdtrueStringNamespace所属的AppId
    formattrueStringNamespace的格式,只能是以下类型: properties、xml、json、yml、yaml
    isPublictrueboolean是否是公共文件
    commentfalseStringNamespace说明
    dataChangeCreatedBytrueStringnamespace的创建人,格式为域账号,也就是sso系统的User ID
  • 返回值 Sample

  1. {
  2. "name": "FX.public-0420-11",
  3. "appId": "100003173",
  4. "format": "properties",
  5. "isPublic": true,
  6. "comment": "test",
  7. "dataChangeCreatedBy": "zhanglea",
  8. "dataChangeLastModifiedBy": "zhanglea",
  9. "dataChangeCreatedTime": "2017-04-20T18:25:49.033+0800",
  10. "dataChangeLastModifiedTime": "2017-04-20T18:25:49.033+0800"
  11. }
  • 返回值说明

如果是properties文件,name = ${appId所属的部门}.${传入的name值} ,例如调用接口传入的name=xy-z, format=properties,应用的部门为框架(FX),那么name=FX.xy-z

如果不是properties文件 name = ${appId所属的部门}.${传入的name值}.${format},例如调用接口传入的name=xy-z, format=json,应用的部门为框架(FX),那么name=FX.xy-z.json

3.2.5 获取某个Namespace当前编辑人接口

Apollo在生产环境(PRO)有限制规则:每次发布只能有一个人编辑配置,且该次发布的人不能是该次发布的编辑人。也就是说如果一个用户A修改了某个namespace的配置,那么在这个namespace发布前,只能由A修改,其它用户无法修改。同时,该用户A无法发布自己修改的配置,必须找另一个有发布权限的人操作。这个接口就是用来获取当前namespace是否有人锁定的接口。在非生产环境(FAT、UAT),该接口始终返回没有人锁定。

  1. {
  2. "namespaceName": "application",
  3. "isLocked": false
  4. }
  • 返回值Sample(被锁定)
  1. {
  2. "namespaceName": "application",
  3. "isLocked": true,
  4. "lockedBy": "song_s" //锁owner
  5. }
3.2.6 新增配置接口
  • URLhttp://{portal_address}/openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items
  • Method : POST
  • Request Params :无
  • 请求内容(Request Body, JSON格式)

    参数名必选类型说明
    keytrueString配置的key,长度不能超过128个字符。非properties格式,key固定为content
    valuetrueString配置的value,长度不能超过20000个字符,非properties格式,value为文件全部内容
    commentfalseString配置的备注,长度不能超过1024个字符
    dataChangeCreatedBytrueStringitem的创建人,格式为域账号,也就是sso系统的User ID
  • Request body sample :

  1. {
  2. "key":"timeout",
  3. "value":"3000",
  4. "comment":"超时时间",
  5. "dataChangeCreatedBy":"zhanglea"
  6. }
  • 返回值Sample
  1. {
  2. "key": "timeout",
  3. "value": "3000",
  4. "comment": "超时时间",
  5. "dataChangeCreatedBy": "zhanglea",
  6. "dataChangeLastModifiedBy": "zhanglea",
  7. "dataChangeCreatedTime": "2016-08-11T12:06:41.818+0800",
  8. "dataChangeLastModifiedTime": "2016-08-11T12:06:41.818+0800"
  9. }
3.2.7 修改配置接口
  • URLhttp://{portal_address}/openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{key}
  • Method : PUT
  • Request Params :无
  • 请求内容(Request Body, JSON格式)

    参数名必选类型说明
    keytrueString配置的key,需和url中的key值一致。非properties格式,key固定为content
    valuetrueString配置的value,长度不能超过20000个字符,非properties格式,value为文件全部内容
    commentfalseString配置的备注,长度不能超过1024个字符
    dataChangeLastModifiedBytrueStringitem的修改人,格式为域账号,也就是sso系统的User ID
  • Request body sample :

  1. {
  2. "key":"timeout",
  3. "value":"3000",
  4. "comment":"超时时间",
  5. "dataChangeLastModifiedBy":"zhanglea"
  6. }
  • 返回值 :无
3.2.8 删除配置接口
3.2.9 发布配置接口
  • URLhttp://{portal_address}/openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases
  • Method : POST
  • Request Params :无
  • Request Body

    参数名必选类型说明
    releaseTitletrueString此次发布的标题,长度不能超过64个字符
    releaseCommentfalseString发布的备注,长度不能超过256个字符
    releasedBytrueString发布人,域账号,注意:如果ApolloConfigDB.ServerConfig中的namespace.lock.switch设置为true的话(默认是false),那么该环境不允许发布人和编辑人为同一人。所以如果编辑人是zhanglea,发布人就不能再是zhanglea。
  • Request Body example

  1. {
  2. "releaseTitle":"2016-08-11",
  3. "releaseComment":"修改timeout值",
  4. "releasedBy":"zhanglea"
  5. }
  • 返回值Sample
  1. {
  2. "appId": "test-0620-01",
  3. "clusterName": "test",
  4. "namespaceName": "application",
  5. "name": "2016-08-11",
  6. "configurations": {
  7. "timeout": "3000",
  8. },
  9. "comment": "修改timeout值",
  10. "dataChangeCreatedBy": "zhanglea",
  11. "dataChangeLastModifiedBy": "zhanglea",
  12. "dataChangeCreatedTime": "2016-08-11T14:03:46.232+0800",
  13. "dataChangeLastModifiedTime": "2016-08-11T14:03:46.235+0800"
  14. }
3.2.10 获取某个Namespace当前生效的已发布配置接口
  1. {
  2. "appId": "test-0620-01",
  3. "clusterName": "test",
  4. "namespaceName": "application",
  5. "name": "2016-08-11",
  6. "configurations": {
  7. "timeout": "3000",
  8. },
  9. "comment": "修改timeout值",
  10. "dataChangeCreatedBy": "zhanglea",
  11. "dataChangeLastModifiedBy": "zhanglea",
  12. "dataChangeCreatedTime": "2016-08-11T14:03:46.232+0800",
  13. "dataChangeLastModifiedTime": "2016-08-11T14:03:46.235+0800"
  14. }

四、错误码说明

正常情况下,接口返回的Http状态码是200,下面列举了Apollo会返回的非200错误码说明。

4.1 400 - Bad Request

客户端传入参数的错误,如操作人不存在,namespace不存在等等,客户端需要根据提示信息检查对应的参数是否正确。

4.2 401 - Unauthorized

接口传入的token非法或者已过期,客户端需要检查token是否传入正确。

4.3 403 - Forbidden

接口要访问的资源未得到授权,比如只授权了对A应用下Namespace的管理权限,但是却尝试管理B应用下的配置。

4.3 404 - Not Found

接口要访问的资源不存在,一般是URL或URL的参数错误。

4.4 405 - Method Not Allowed

接口访问的Method不正确,比如应该使用POST的接口使用了GET访问等,客户端需要检查接口访问方式是否正确。

4.4 500 - Internal Server Error

其它类型的错误默认都会返回500,对这类错误如果应用无法根据提示信息找到原因的话,可以找Apollo研发团队一起排查问题。