我正在尝试使用工作台 api 从 Node.js 使用 axios 包创建一个新的合同实例:
首先,我根据文档请求创建了服务主体,用于获取不记名令牌并访问 api 资源。
然后,对 /api/v1/applications/workflows/ 执行 GET 请求,得到以下结果:
{
"id": 27,
"name": "ScompCertificados",
"description": "Manejo del flujo de la aplicación Scomp",
"displayName": "Scomp certificados",
"applicationId": 27,
"constructorId": 101,
"startStateId": 74,
"initiators": [
"AFP"
],
"properties": [
{
"id": 174,
"name": "Estado",
"description": "Estado del contrato",
"displayName": "Estado",
"type": {
"id": 1,
"name": "state",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 175,
"name": "Rutdeljubilado",
"description": "Da a conocer el rut del jubilado a quien se le genero un certificado de saldo",
"displayName": "Rut del jubilado",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 176,
"name": "Hashdeldocumento",
"description": "Da a conocer el hash donde se encuentra el certificado de saldo",
"displayName": "Hash del certificado de saldo",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 177,
"name": "Saldototal",
"description": "El saldo total de jubilado, ingresado manualmente por su AFP",
"displayName": "Saldo total",
"type": {
"id": 3,
"name": "money",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 178,
"name": "OfferPrice",
"description": "Posibles estados: 0",
"displayName": "Estado del certificado",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
}
],
"constructor": {
"id": 101,
"name": "",
"description": null,
"displayName": "",
"parameters": [
{
"id": 99,
"name": "ingreserutdeljubilado",
"description": "El rut del jubilado sin puntos ni guion",
"displayName": "Ingrese rut del jubilado",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 100,
"name": "ingresesaldototaldeljubilado",
"description": "El saldo total debe ser ingresado manualmente",
"displayName": "Ingrese saldo total del jubilado",
"type": {
"id": 3,
"name": "money",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 101,
"name": "ingreseelhashdeldocumento",
"description": "El hash del documento donde se almacena el pdf del certificado de saldo",
"displayName": "Ingrese el hash de donde se encuentra el certificado de saldo",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
}
],
"workflowId": 27
},
"functions": [
{
"id": 101,
"name": "",
"description": null,
"displayName": "",
"parameters": [
{
"id": 99,
"name": "ingreserutdeljubilado",
"description": "El rut del jubilado sin puntos ni guion",
"displayName": "Ingrese rut del jubilado",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 100,
"name": "ingresesaldototaldeljubilado",
"description": "El saldo total debe ser ingresado manualmente",
"displayName": "Ingrese saldo total del jubilado",
"type": {
"id": 3,
"name": "money",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
},
{
"id": 101,
"name": "ingreseelhashdeldocumento",
"description": "El hash del documento donde se almacena el pdf del certificado de saldo",
"displayName": "Ingrese el hash de donde se encuentra el certificado de saldo",
"type": {
"id": 2,
"name": "string",
"applicationId": 0,
"elementType": null,
"elementTypeId": 0,
"enumValues": null
}
}
],
"workflowId": 27
}
],
"startState": {
"id": 74,
"name": "CertificadoGenerado",
"description": "The item is available",
"displayName": "Certificado generado",
"percentComplete": 100,
"value": 0,
"style": "Success",
"workflowStateTransitions": []
},
"states": [
{
"id": 74,
"name": "CertificadoGenerado",
"description": "The item is available",
"displayName": "Certificado generado",
"percentComplete": 100,
"value": 0,
"style": "Success",
"workflowStateTransitions": []
}
]
}
接下来,基于推断(因为执行 post 的文档对于 Node.js 来说不够详细)使用 axios 执行 POST,如下所示:
const request = await axios({
method: "POST",
url: `${WORKBENCH_API_URL}/api/v1/contracts?workflowId=27&contractCodeId=27&connectionId=1`,
headers: { 'Authorization': `Bearer ${token.access_token}` },
data: {
workflowActionInput: {
"workflowFunctionId": 101,
"workflowFunctionParameters": [
{
"name": "ingreserutdeljubilado",
"value": "1234567890",
"workflowFunctionParameterId": 99
},
{
"name": "ingresesaldototaldeljubilado",
"value": "250000000",
"workflowFunctionParameterId": 100
},
{
"name": "ingreseelhashdeldocumento",
"value": "FRfIYIfjTDFJHKYT",
"workflowFunctionParameterId": 101
}
]
}
}
});
最后,响应的日志显示:
{ Error: Request failed with status code 500
at createError (/home/ubuntu/workspace/node_modules/axios/lib/core/createError.js:16:15)
at settle (/home/ubuntu/workspace/node_modules/axios/lib/core/settle.js:18:12)
at IncomingMessage.handleStreamEnd (/home/ubuntu/workspace/node_modules/axios/lib/adapters/http.js:201:11)
at IncomingMessage.emit (events.js:202:15)
at endReadableNT (_stream_readable.js:1129:12)
at processTicksAndRejections (internal/process/next_tick.js:76:17)
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json;charset=utf-8',
Authorization:
'Bearer <token>',
'User-Agent': 'axios/0.18.0',
'Content-Length': 334 },
method: 'post',
url:
'<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
data:
'{"workflowFunctionId":101,"workflowFunctionParameters":[{"name":"ingreserutdeljubilado","value":"1234567890","workflowFunctionParameterId":99},{"name":"ingresesaldototaldeljubilado","value":"250000000","workflowFunctionParameterId":100},{"name":"ingresehashdeldocumento","value":"FRfIYIfjTDFJHKYT","workflowFunctionParameterId":101}]}' },
request:
ClientRequest {
_events:
[Object: null prototype] {
socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish] },
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: '<blockchain_App_url>',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 8,
connecting: false,
_hadError: false,
_handle: [TLSWrap],
_parent: null,
_host: '<blockchain_App_url>',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 25,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object] },
connection:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: '<blockchain_App_url>',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 8,
connecting: false,
_hadError: false,
_handle: [TLSWrap],
_parent: null,
_host: '<blockchain_App_url>',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 25,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object] },
_header:
'POST /api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1 HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: Bearer <token>\r\nUser-Agent: axios/0.18.0\r\nContent-Length: 334\r\nHost: <blockchain_App_url>\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent:
Agent {
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object] },
socketPath: undefined,
timeout: undefined,
method: 'POST',
path:
'/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
_ended: true,
res:
IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
connection: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 500,
statusMessage: 'Internal Server Error',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular],
responseUrl:
'<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
redirects: [] },
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable:
Writable {
_writableState: [WritableState],
writable: true,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 334,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl:
'<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1' },
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]:
[Object: null prototype] {
accept: [Array],
'content-type': [Array],
authorization: [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array] } },
response:
{ status: 500,
statusText: 'Internal Server Error',
headers:
{ 'transfer-encoding': 'chunked',
'content-type': 'application/json',
server: 'Kestrel',
'request-context': 'appId=cid-v1:db0d0b41-4c65-4302-8151-77d69bdb0b7b',
'x-correlation-id': '56831aa5-6ba1-42a2-9e19-16069f525716',
'set-cookie': [Array],
date: 'Thu, 14 Feb 2019 13:17:31 GMT',
connection: 'close' },
config:
{ adapter: [Function: httpAdapter],
transformRequest: [Object],
transformResponse: [Object],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers: [Object],
method: 'post',
url:
'<blockchain_App_url>/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
data:
'{"workflowFunctionId":101,"workflowFunctionParameters":[{"name":"ingreserutdeljubilado","value":"1234567890","workflowFunctionParameterId":99},{"name":"ingresesaldototaldeljubilado","value":"250000000","workflowFunctionParameterId":100},{"name":"ingresehashdeldocumento","value":"FRfIYIfjTDFJHKYT","workflowFunctionParameterId":101}]}' },
request:
ClientRequest {
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header:
'POST /api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1 HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: Bearer <token>\r\nUser-Agent: axios/0.18.0\r\nContent-Length: 334\r\nHost: scompblockchain1-6jii2u-api.azurewebsites.net\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path:
'/api/v2/contracts?workflowId=27&contractCodeId=27&connectionId=1',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Writable],
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]: [Object] },
data: { error: 'Internal Server Error' } } }
抱歉,如果内容太长,只是想确保提供每个细节。这是 api 的问题,代码语法还是天蓝色的问题?
PD:azure 上的所有权限都已被授予文档点。