API
API使用方法
首先需要定义数据表描述文件(如:test.schema),定义存储在系统中的数据结构,表的各个字段(Fields)按文件中的排列顺序排列,字段类型支持(int8,int16,uint16,int32,uint32,int64,uint64,float32,float64,string,bool,file,date,datetime),表中必须有一个(int32/uint32/int64/uint64)类型的字段作为主键,且必须为第一个字段。
test.schema内容如下:
{
"TabComment":"测试",
"TabName":"TestTab",
"Insert":"additem",
"Update":"updateitem",
"Delete":"deleteitem",
"Contract":"datazt",
"ContractAddr":"https://dev.bingooglobal.com/api/yottachain_rpc",
"PrivKey":"5Jjv6rvzUqhkWcA.....................fyJYnQ8CGNW9xo3F",
"Fields":
[
{
"FieldComment":"记录ID",
"FieldName":"id",
"FieldType":"uint64",
"Primarykey":true
},
{
"FieldComment":"INT8类型",
"FieldName":"fint8",
"EncLevel":0,
"FieldType":"int8"
},
{
"FieldComment":"INT16类型",
"FieldName":"fint16",
"EncLevel":1,
"FieldType":"int16"
},
{
"FieldComment":"UINT16类型",
"FieldName":"fuint16",
"EncLevel":2,
"FieldType":"uint16"
},
{
"FieldComment":"INT32类型",
"FieldName":"fint32",
"FieldType":"int32"
},
{
"FieldComment":"UINT32类型",
"FieldName":"fuint32",
"FieldType":"uint32"
},
{
"FieldComment":"INT64类型",
"FieldName":"fint64",
"FieldType":"int64"
},
{
"FieldComment":"UINT64类型",
"FieldName":"fuint64",
"FieldType":"uint64"
},
{
"FieldComment":"FLOAT32类型",
"FieldName":"ffloat32",
"FieldType":"float32"
},
{
"FieldComment":"FLOAT64类型",
"FieldName":"ffloat64",
"FieldType":"float64"
},
{
"FieldComment":"DATE类型",
"FieldName":"fdate",
"FieldType":"date"
},
{
"FieldComment":"DATETIME类型",
"FieldName":"fdatetime",
"FieldType":"datetime"
},
{
"FieldName":"fbool",
"FieldComment":"BOOL类型",
"FieldType":"bool"
},
{
"FieldName":"fstring",
"FieldComment":"STR类型",
"Length":30,
"FieldType":"string"
},
{
"FieldComment":"文件类型",
"FieldName":"ffile",
"FieldType":"file"
}
]
}
"EncLevel":默认0,使用行密钥列密钥加密
1,使用行密钥加密
2,不加密
"Length":设置string类型字段长度
使用API表导入程序,将test.schema文件导入系统
执行: dc createtab /root/test.schema
第二步,需要按照test.schema表描述,在EOS私链创建一个数据表,即自动创建一个合约用来读写结构化数据,合约帐户(schema. Contract),表名(schema. TabName),插入方法(schema. Insert),更新方法(schema. Update),删除方法(schema. delete)...并按照(schema.Fields)描述的字段类型,按顺序在合约里创建表字段
1.file类型字段按string类型创建
2.float32类型字段,如果加密按int32类型创建,不加密则按float32类型创建
3.float64类型字段,如果加密按int64类型创建,不加密则按float64类型创建
4.bool类型字段按int8类型创建
5.date类型字段按int64类型创建
6.datetime类型字段按int64类型创建
完成上面两步后,就可以按照后面提供的API接口对该表进行插入,更新,删除,按主键查询,遍历...等操作
当应用层通过下面API的(insert)接口插入一条记录时,系统会将各个字段进行加密(加密规则,请查看产品黄皮书),对于文件类型字段将文件内容加密,加密后内容写入本地文件系统,然后调用第二步创建的EOS合约,将加密后的字段值写入合约。
API接口
1、注册和登陆
Get /login?uid=testuser1&secret_key=123456
uid:用户名
secret_key:密码
用户如果不存在,创建用户
返回:
{"access_token":" test.token.1"}
APP在调用后需API接口时需要出示令牌,将token填入HTTP请求头,如
Authorization: test.token.1
也可以放到url,Query字段,如:
/list?token= test.token.1&....
所有接口可能返回错误:当ResponseCode=500时,返回如下text/json
{"Code":2,"Msg":"INVALID_TABID","Detail":"..."}
当ResponseCode=200时,调用成功
暂定几个错误码,后续更新:
var SERVER_ERROR = &ErrorMessage{0x00, "SERVER_ERROR", ""}
var INVALID_TOKEN = &ErrorMessage{0x01, "INVALID_TOKEN", ""}
var INVALID_TABID = &ErrorMessage{0x02, "INVALID_TABID", ""}
var TAB_ALREADY_INITED = &ErrorMessage{0x03, "TAB_ALREADY_INITED", ""}
var ARGS_ERROR = &ErrorMessage{0x04, "ARGS_ERROR", ""}
var NO_TAB_PERMISSION = &ErrorMessage{0x05, "NO_TAB_PERMISSION", ""}
var NO_FIELD_PERMISSION = &ErrorMessage{0x06, "NO_FIELD_PERMISSION", ""}
var INVALID_USERNAME = &ErrorMessage{0x07, "INVALID_USERNAME", ""}
var BAD_REQUEST = &ErrorMessage{0x08, "BAD_REQUEST", ""}
var FIELD_TOO_LARGE = &ErrorMessage{0x09, "FIELD_TOO_LARGE", ""}
var INVALID_FIELD_VALUE = &ErrorMessage{0x10, "INVALID_FIELD_VALUE", ""}
var NO_RECORD = &ErrorMessage{0x11, "NO_RECORD", ""}
var INVALID_CDRID = &ErrorMessage{0x12, "INVALID_CDRID", ""}
var DUPLICATE_KEY = &ErrorMessage{0x13, "DUPLICATE_KEY", ""}
每当调用API接口,返回INVALID_TOKEN错误时,表示token过期,需要重新调用登陆接口获取token
2、遍历表接口
GET /list (注意HTTP请求头加入token,下同)
返回系统中已经创建了多少表,返回表ID,名称,功能描述,当前用户是否允许访问,格式ContentType:text/json如:
[{"TabComment":"description","TabId":1,"TabName":"testtab1","Allow":true}, {"TabComment":"description","TabId":2,"TabName":"testtab2","Allow":false}]
TabComment:表的功能描述
TabName:表名
TabId:表ID
Allow:允许向此表插入记录
3、获取指定表的结构接口
GET / 1/schema
输入:第一级路径是表的ID,接口2中的TabId字段值
返回表结构,如下:
{"TabComment":"description","TabId":1,"TabName":"test","Allow":false,"Fields":[{"FieldComment":"文件ID","FieldName":"ID","FieldType":"int32","Primarykey":true,"Allow":false},{"FieldComment":"作者","FieldName":"Author","FieldType":"string","Primarykey":false,"Allow":false},{"FieldComment":"插入时间","FieldName":"CreateTime","FieldType":"int64","Primarykey":false,"Allow":false},{"FieldComment":"文件内容","FieldName":"FileLocation","FieldType":"file","Primarykey":false,"Allow":false}]}
FieldComment:字段描述
FieldName:字段名
Primarykey:是否主健
FieldType:字段类型,包括int8,int16.....和 file(文件类型字段)
Allow:对此字段有读取和修改权限
只有拥有所有字段的访问权限,该用户才拥有向表中插入记录,删除记录的权限。
4. 初始化指定表的访问权限
GET /1/init
输入:第一级路径是表的ID,接口2中的TabId字段值
当系统创建表后,暂时没有任何人有权限访问此表,这时当前用户如果执行初始化接口,就拥有了该表访问权,如果该表已经被其他用户初始化过,那么当前用户就无法初始化,想获得该表访问权,必须让其他用户授权给当前用户,即(接口5)
成功返回: "Content-Type", "text/ json " 格式,与接口3的返回相同,且Allow=true
{"TabComment":"description","TabId":1,"TabName":"test","Allow": true,"Fields":[{"FieldComment":"文件ID","FieldName":"ID","FieldType":"int32","Primarykey":true,"Allow": true },{"FieldComment":"作者","FieldName":"Author","FieldType":"string","Primarykey":false,"Allow": true },{"FieldComment":"插入时间","FieldName":"CreateTime","FieldType":"int64","Primarykey":false,"Allow": true },{"FieldComment":"文件内容","FieldName":"FileLocation","FieldType":"file","Primarykey":false,"Allow": true }]}
失败返回:"Content-Type", "text/json"错误消息
初始化成功后,当前用户拥有该表的全部权限(插入,删除,修改,读取,遍历任何字段,也可以将权限授权给其他用户)
5. 授权指定表的指定字段给其他用户
GET /1/auth?username=testuser2&Author=1& CreateTime=1
输入:username,将授权给指定用户表权限,第一级路径是表的ID,接口2中的TabId字段值
例如上面的指令,当前用户把表1中字段名为CreateTime和Author的列权限授权给用户testuser2, 当然当前用户必须拥有该表的对应字段CreateTime和Author的列权限,否则返回NO_FIELD_PERMISSION;字段名Author和CreateTime必须等于1,其他认为不授权该字段,且大小写敏感,使用表结构中给出的字段名
成功返回:用户testuser2对表1的权限描述,格式与接口3的返回相同,如下
{"TabComment":"description","TabId":1,"TabName":"test","Allow": false,"Fields":[{"FieldComment":"文件ID","FieldName":"ID","FieldType":"int32","Primarykey":true,"Allow": false},{"FieldComment":"作者","FieldName":"Author","FieldType":"string","Primarykey":false,"Allow": true },{"FieldComment":"插入时间","FieldName":"CreateTime","FieldType":"int64","Primarykey":false,"Allow": true},{"FieldComment":"文件内容","FieldName":"FileLocation","FieldType":"file","Primarykey":false,"Allow": false }]}
将列Author和CreateTime权限授权给用户testuser2后, 用户testuser2暂时还不能对表1进行插入,修改,删除,查询等操作,只有当前用户授权了某一行记录(比如ID=1的记录),testuser2才可 以对ID=1的记录的Author和CreateTime字段进行修改,查询操作。行授权接口请看(接口6)
如果想把表1的全部控制权限授权给用户testuser2,可不填字段列表,如下:
GET / 1/auth?username=testuser2
当然,前提是当前用户具有表1的全部控制权限,否则还是会返回无列权限错误
用户testuser2拥有了表1的全部控制权限,意味着它和testuser1一样,可以对表进行插入,删除,修改,读取,遍历任何记录任何字段,也可以将权限授权给其他用户。
6. 授权指定表的指定行权限给其他用户
GET /1/share?username=testuser2&ID=1
输入:username,将授权给指定用户ID=1的行权限,第一级路径是表的ID,接口2中的TabId字段值
如果用户拥有列Author和CreateTime的权限(接口5可以授权列权限),用户testuser2就可以对记录1的Author和CreateTime进行查询和修改
行授权成功,返回授权成功的行ID
{"ID":1}
7.对指定表增加一条记录
POST /1/insert
第一级路径是表的ID,接口2中的TabId字段值
如果表包含文件类型字段,需要上传文件,所以Content-Type必须是 multipart/form-data,相当于下面这样,注意表单中字段名必须是表结构中给出的字段名,大小写敏感

通过设置multipart.Part的Content-Disposition的值来传入文件名
如:
Content-type: multipart/form-data; boundary=---+boundary
Content-Disposition: form-data; name=file;filename=a.doc;
这样查询记录时,会把文件名"a.doc "显示在json中
注意:提交的RequestBody第一个字段,必须是表主键,如ID(系统需要先取到主键值来计算行密钥)
如果不上传文件类型字段,可以不使用multipart/form-data格式
成功返回插入结果:
{"Author":"张三封","CreateTime":34,"FileLocation":"a.doc","ID":2}
重复插入会有DUPLICATE_KEY 错误
8.读取记录
Get /1/query?ID=2
第一级路径是表的ID,接口2中的TabId字段值,ID是主健,注意字段名必须与表1结构中的主健字段名一致
如果当前用户无表权限,会返回对应错误
返回有权限列的字段值,比如如果没有列(CreateTime)的权限
则返回:
{"Author":"张三封","FileLocation":" a.doc ","ID":2}
FileLocation字段时文件字段,返回的是上传时传入的文件名
记录不存在,返回NO_RECORD错误
9.下载文件
Get /1/down?ID=2
第一级路径是表的ID,接口2中的TabId字段值,ID是主健,注意字段名必须与表1结构中的主健字段名一致,返回ID=2的记录中文件数据流
如果记录中有两个文件类型字段,需要指定下载那个字段的文件(fieldname=?)
Get /1/down?ID=2&fieldname= FileLocation
当然,当前用户需要有该文件类型字段的访问权限
记录不存在,返回NO_RECORD错误
10.删除记录
Get /1/delete? ID=2
第一级路径是表的ID,接口2中的TabId字段值,ID是主健,注意字段名必须与表1结构中的主健字段名一致
功能是删除表1中主健值是2的记录,当前用户必须有该表及所有字段权限才可删除
成功返回:
{"ID":2}
11.修改记录
POST /1/update
第一级路径是表的ID,接口2中的TabId字段值
如果表包含文件类型字段,需要上传文件,所以Content-Type必须是 multipart/form-data,相当于下面这样,注意表单中字段名必须是表结构中给出的字段名,大小写敏感

如果不上传文件类型字段,可以不使用multipart/form-data格式
成功返回插入结果:
{"Author":"里斯" ,"FileLocation":"软件需求.pdf","ID":2}
只返回修改的字段,没有修改的字段如CreateTime没显示
如果当前用户没有字段Author权限,返回修改失败
注意:如果提交的RequestBody不包含某字段,比如不包含Author字段,表示不修改该字段,如果含有Author字段,但Author值为空字符串,则使用空字符串值更新对应字段值
12.遍历记录
Get /1/list? startid=1&limit=10
第一级路径是表的ID,接口2中的TabId字段值
startid:主键的起始ID
limit:行数
返回:
[{"Author":"张三封","FileLocation":"a.doc","ID":1},
{"Author":"张","FileLocation":"软件需求.pdf ","ID":2}
]
不足10行,表示遍历完
注意:对于没有全部表字段权限的用户,list只返回被授权的行记录