Skip to content

填写API文档模板并生成MarkDown文档

zhangxin edited this page Apr 14, 2017 · 1 revision

生成并填写API文档模板

当新添加一个API后,例如APICreateVmInstanceMsg,使用如下命令生成对应的API文档模块:

./runMavenProfile doc

在APICreateVmInstanceMsg.java所在目录(例如./header/src/main/java/org/zstack/header/vm/)会生成两个API文档模板文件:

  • ./header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsgDoc_zh_cn.groovy
  • ./header/src/main/java/org/zstack/header/vm/APICreateVmInstanceEventDoc_zh_cn.groovy

其中APICreateVmInstanceMsgDoc_zh_cn.groovy是API请求文档模板,APICreateVmInstanceEventDoc_zh_cn.groovy是API返回文档模板。

大部分字段都已为你自动生成,有部分是需要你填写的,具体参考下面例子:

### APICreateVmInstanceMsgDoc_zh_cn.groovy

package org.zstack.header.vm

import org.zstack.header.vm.APICreateVmInstanceEvent

doc {
    title "创建云主机(CreateVmInstance)"

    category "云主机"

    desc "创建一个新的云主机"

    rest {
        request {
			url "POST /v1/vm-instances"


            header (OAuth: 'the-session-uuid')

            clz APICreateVmInstanceMsg.class

            desc ""
            
			params {

				column {
					name "name"
					enclosedIn "params"
					desc "云主机名称"
					location "body"
					type "String"
					optional false
					since "0.6"
					
				}
				column {
					name "instanceOfferingUuid"
					enclosedIn "params"
					desc "计算规格UUID。指定云主机的CPU、内存等参数。"
					location "body"
					type "String"
					optional false
					since "0.6"
					
				}
				column {
					name "imageUuid"
					enclosedIn "params"
					desc "镜像UUID。云主机的根云盘会从该字段指定的镜像创建。"
					location "body"
					type "String"
					optional false
					since "0.6"
					
				}
				column {
					name "l3NetworkUuids"
					enclosedIn "params"
					desc "三层网络UUID列表。可以指定一个或多个三层网络,云主机会在每个网络上创建一个网卡。"
					location "body"
					type "List"
					optional false
					since "0.6"
					
				}
				column {
					name "type"
					enclosedIn "params"
					desc "云主机类型。保留字段,无需指定。"
					location "body"
					type "String"
					optional true
					since "0.6"
					values ("UserVm","ApplianceVm")
				}
				column {
					name "rootDiskOfferingUuid"
					enclosedIn "params"
					desc "根云盘规格UUID。如果`imageUuid`字段指定的镜像类型是ISO,该字段必须指定以确定需要创建的根云盘大小。如果镜像类型是非ISO,该字段无需指定。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "dataDiskOfferingUuids"
					enclosedIn "params"
					desc "云盘规格UUID列表。可以指定一个或多个云盘规格UUID(UUID可以重复)为云主机创建一个或多个数据云盘。"
					location "body"
					type "List"
					optional true
					since "0.6"
					
				}
				column {
					name "zoneUuid"
					enclosedIn "params"
					desc "区域UUID。若指定,云主机会在指定区域创建。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "clusterUuid"
					enclosedIn "params"
					desc "集群UUID。若指定,云主机会在指定集群创建,该字段优先级高于`zoneUuid`。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "hostUuid"
					enclosedIn "params"
					desc "物理机UUID。若指定,云主机会在指定物理机创建,该字段优先级高于`zoneUuid`和`clusterUuid`。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "primaryStorageUuidForRootVolume"
					enclosedIn "params"
					desc "主存储UUID。若指定,云主机的根云盘会在指定主存储创建。"
					location "body"
					type "String"
					optional true
					since "1.8"
					
				}
				column {
					name "description"
					enclosedIn "params"
					desc "云主机的详细描述"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "defaultL3NetworkUuid"
					enclosedIn "params"
					desc "默认三层网络UUID。当在`l3NetworkUuids`指定了多个三层网络时,该字段指定提供默认路由的三层网络。若不指定,`l3NetworkUuids`的第一个网络被选为默认网络。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "resourceUuid"
					enclosedIn "params"
					desc "资源UUID。若指定,云主机会使用该字段值作为UUID。"
					location "body"
					type "String"
					optional true
					since "0.6"
					
				}
				column {
					name "systemTags"
					enclosedIn ""
					desc "云主机系统标签"
					location "body"
					type "List"
					optional true
					since "0.6"
					
				}
				column {
					name "userTags"
					enclosedIn ""
					desc "云主机用户标签"
					location "body"
					type "List"
					optional true
					since "0.6"
					
				}
			}
        }

        response {
            clz APICreateVmInstanceEvent.class
        }
    }
}

APICreateVmInstanceEventDoc_zh_cn.groovy

package org.zstack.header.vm

import org.zstack.header.errorcode.ErrorCode
import org.zstack.header.vm.VmInstanceInventory

doc {

	title "云主机清单"

	ref {
		name "error"
		path "org.zstack.header.vm.APICreateVmInstanceEvent.error"
		desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
		type "ErrorCode"
		since "0.6"
		clz ErrorCode.class
	}
	ref {
		name "inventory"
		path "org.zstack.header.vm.APICreateVmInstanceEvent.inventory"
		desc "null"
		type "VmInstanceInventory"
		since "0.6"
		clz VmInstanceInventory.class
	}
}

同时你需要给API请求和返回都添加__example__函数,例如:

APICreateVmInstanceMsg:

    public static APICreateVmInstanceMsg __example__() {
        APICreateVmInstanceMsg msg = new APICreateVmInstanceMsg();
        msg.setName("vm1");
        msg.setDescription("this is a vm");
        msg.setClusterUuid(uuid());
        msg.setDataDiskOfferingUuids(asList(uuid(), uuid()));
        msg.setImageUuid(uuid());
        msg.setInstanceOfferingUuid(uuid());
        msg.setL3NetworkUuids(asList(uuid()));
        return msg;
    }

APICreateVmInstanceEvent:

   public static APICreateVmInstanceEvent __example__() {
        APICreateVmInstanceEvent evt = new APICreateVmInstanceEvent();

        String defaultL3Uuid = uuid();
        String rootVolumeUuid = uuid();

        VmInstanceInventory vm = new VmInstanceInventory();
        vm.setName("Test-VM");
        vm.setUuid(uuid());
        vm.setAllocatorStrategy(HostAllocatorConstant.LAST_HOST_PREFERRED_ALLOCATOR_STRATEGY_TYPE);
        vm.setClusterUuid(uuid());
        vm.setCpuNum(1);
        vm.setCreateDate(new Timestamp(System.currentTimeMillis()));
        vm.setDefaultL3NetworkUuid(defaultL3Uuid);
        vm.setDescription("web server VM");
        vm.setHostUuid(uuid());
        vm.setHypervisorType("KVM");
        vm.setImageUuid(uuid());
        vm.setInstanceOfferingUuid(uuid());
        vm.setLastHostUuid(uuid());
        vm.setMemorySize(SizeUnit.GIGABYTE.toByte(8));
        vm.setPlatform("Linux");
        vm.setRootVolumeUuid(rootVolumeUuid);
        vm.setState(VmInstanceState.Running.toString());
        vm.setType(VmInstanceConstant.USER_VM_TYPE);
        vm.setLastOpDate(new Timestamp(System.currentTimeMillis()));
        vm.setZoneUuid(uuid());

        VolumeInventory vol = new VolumeInventory();
        vol.setName(String.format("Root-Volume-For-VM-%s", vm.getUuid()));
        vol.setCreateDate(new Timestamp(System.currentTimeMillis()));
        vol.setLastOpDate(new Timestamp(System.currentTimeMillis()));
        vol.setType(VolumeType.Root.toString());
        vol.setUuid(rootVolumeUuid);
        vol.setSize(SizeUnit.GIGABYTE.toByte(100));
        vol.setActualSize(SizeUnit.GIGABYTE.toByte(20));
        vol.setDeviceId(0);
        vol.setState(VolumeState.Enabled.toString());
        vol.setFormat("qcow2");
        vol.setDiskOfferingUuid(uuid());
        vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", rootVolumeUuid, rootVolumeUuid));
        vol.setStatus(VolumeStatus.Ready.toString());
        vol.setPrimaryStorageUuid(uuid());
        vol.setVmInstanceUuid(vm.getUuid());
        vol.setRootImageUuid(vm.getImageUuid());
        vm.setAllVolumes(asList(vol));

        VmNicInventory nic = new VmNicInventory();
        nic.setVmInstanceUuid(vm.getUuid());
        nic.setCreateDate(vm.getCreateDate());
        nic.setLastOpDate(vm.getLastOpDate());
        nic.setDeviceId(0);
        nic.setGateway("192.168.1.1");
        nic.setIp("192.168.1.10");
        nic.setL3NetworkUuid(defaultL3Uuid);
        nic.setNetmask("255.255.255.0");
        nic.setMac("00:0c:29:bd:99:fc");
        nic.setUsedIpUuid(uuid());
        nic.setUuid(uuid());
        vm.setVmNics(asList(nic));

        evt.setInventory(vm);

        return evt;
    }

注意__example__函数必须是static函数。

Query API的请求比较特殊,其__example__函数返回的不是该class的一个实例,而是一个List,包含的是Query的条件字符串,例如:

APIQueryVmInstanceMsg:

    public static List<String> __example__() {
        return asList("name=vm1", "vmNics.ip=192.168.20.100");
    }

生产最终的MarkDown文件

填写完模板后,运行如下unit test可以生成最终的Markdown文件查看效果:

mvn  test -Dtest=TestGenerateMarkDownDoc -Dclasses=APIQueryVmInstanceMsg,APICreateVmInstanceMsg

这里classes参数后跟的是需要产生Markdown文件的API名