mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-20 00:25:09 +00:00
Update the REST Example (#689)
1. The default chaincode use Capitalized JSON Names, whereas for new asset the REST validation didn't.. Adjusted so it matches the chaincode Signed-off-by: Matthew B White <whitemat@uk.ibm.com>
This commit is contained in:
parent
57919f528d
commit
9fa171f824
5 changed files with 68 additions and 67 deletions
|
|
@ -185,7 +185,7 @@ curl --include --header "X-Api-Key: ${SAMPLE_APIKEY}" --request OPTIONS http://l
|
|||
### Create an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request POST --data '{"id":"asset7","color":"red","size":42,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request POST --data '{"ID":"asset7","Color":"red","Size":42,"Owner":"Jean","AppraisedValue":101}' http://localhost:3000/api/assets
|
||||
```
|
||||
|
||||
The response should include a `jobId` which you can use to check the job status in next step
|
||||
|
|
@ -237,13 +237,13 @@ You should see the newly created asset, for example
|
|||
### Update an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PUT --data '{"id":"asset7","color":"red","size":11,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PUT --data '{"ID":"asset7","Color":"red","Size":11,"Owner":"Jean","AppraisedValue":101}' http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Transfer an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PATCH --data '[{"op":"replace","path":"/owner","value":"Ashleigh"}]' http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PATCH --data '[{"op":"replace","path":"/Owner","value":"Ashleigh"}]' http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Delete an asset...
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ content-type: application/json
|
|||
X-Api-Key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 42,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
"ID": "asset7",
|
||||
"Color": "red",
|
||||
"Size": 42,
|
||||
"Owner": "Jean",
|
||||
"AppraisedValue": 101
|
||||
}
|
||||
|
||||
### Read job status
|
||||
|
|
@ -62,11 +62,11 @@ content-type: application/json
|
|||
X-Api-Key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 11,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
"ID": "asset7",
|
||||
"Color": "red",
|
||||
"Size": 11,
|
||||
"Owner": "Jean",
|
||||
"AppraisedValue": 101
|
||||
}
|
||||
|
||||
### Transfer asset
|
||||
|
|
@ -78,7 +78,7 @@ X-Api-Key: {{api-key}}
|
|||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/owner",
|
||||
"path": "/Owner",
|
||||
"value": "Ashleigh"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -208,11 +208,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.post('/api/assets')
|
||||
.send({
|
||||
identifier: 'asset3',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
wrongidfield: 'asset3',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(400);
|
||||
|
|
@ -227,7 +227,7 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
{
|
||||
location: 'body',
|
||||
msg: 'must be a string',
|
||||
param: 'id',
|
||||
param: 'ID',
|
||||
},
|
||||
],
|
||||
message: 'Invalid request body',
|
||||
|
|
@ -239,11 +239,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.post('/api/assets')
|
||||
.send({
|
||||
id: 'asset3',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
ID: 'asset3',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(202);
|
||||
|
|
@ -401,11 +401,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.put('/api/assets/asset1')
|
||||
.send({
|
||||
id: 'asset3',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
ID: 'asset3',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'NOTTHERIGHTAPIKEY');
|
||||
expect(response.statusCode).toEqual(401);
|
||||
|
|
@ -424,11 +424,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.put('/api/assets/asset1')
|
||||
.send({
|
||||
id: 'asset2',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
ID: 'asset2',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(400);
|
||||
|
|
@ -448,11 +448,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.put('/api/assets/asset1')
|
||||
.send({
|
||||
identifier: 'asset1',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
wrongID: 'asset1',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(400);
|
||||
|
|
@ -467,7 +467,7 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
{
|
||||
location: 'body',
|
||||
msg: 'must be a string',
|
||||
param: 'id',
|
||||
param: 'ID',
|
||||
},
|
||||
],
|
||||
message: 'Invalid request body',
|
||||
|
|
@ -479,11 +479,11 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
const response = await request(app)
|
||||
.put('/api/assets/asset1')
|
||||
.send({
|
||||
id: 'asset1',
|
||||
color: 'red',
|
||||
size: 5,
|
||||
owner: 'Brad',
|
||||
appraisedValue: 400,
|
||||
ID: 'asset1',
|
||||
Color: 'red',
|
||||
Size: 5,
|
||||
Owner: 'Brad',
|
||||
AppraisedValue: 400,
|
||||
})
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(202);
|
||||
|
|
@ -501,7 +501,7 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
it('PATCH should respond with 401 unauthorized json when an invalid API key is specified', async () => {
|
||||
const response = await request(app)
|
||||
.patch('/api/assets/asset1')
|
||||
.send([{ op: 'replace', path: '/owner', value: 'Ashleigh' }])
|
||||
.send([{ op: 'replace', path: '/Owner', value: 'Ashleigh' }])
|
||||
.set('X-Api-Key', 'NOTTHERIGHTAPIKEY');
|
||||
expect(response.statusCode).toEqual(401);
|
||||
expect(response.header).toHaveProperty(
|
||||
|
|
@ -531,7 +531,7 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
errors: [
|
||||
{
|
||||
location: 'body',
|
||||
msg: "path must be '/owner'",
|
||||
msg: "path must be '/Owner'",
|
||||
param: '[0].path',
|
||||
value: '/color',
|
||||
},
|
||||
|
|
@ -544,7 +544,7 @@ describe('Asset Transfer Besic REST API', () => {
|
|||
it('PATCH should respond with 202 accepted json', async () => {
|
||||
const response = await request(app)
|
||||
.patch('/api/assets/asset1')
|
||||
.send([{ op: 'replace', path: '/owner', value: 'Ashleigh' }])
|
||||
.send([{ op: 'replace', path: '/Owner', value: 'Ashleigh' }])
|
||||
.set('X-Api-Key', 'ORG1MOCKAPIKEY');
|
||||
expect(response.statusCode).toEqual(202);
|
||||
expect(response.header).toHaveProperty(
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ export const assetsRouter = express.Router();
|
|||
|
||||
assetsRouter.get('/', async (req: Request, res: Response) => {
|
||||
logger.debug('Get all assets request received');
|
||||
|
||||
try {
|
||||
const mspId = req.user as string;
|
||||
const contract = req.app.locals[mspId]?.assetContract as Contract;
|
||||
|
|
@ -59,11 +58,11 @@ assetsRouter.get('/', async (req: Request, res: Response) => {
|
|||
assetsRouter.post(
|
||||
'/',
|
||||
body().isObject().withMessage('body must contain an asset object'),
|
||||
body('id', 'must be a string').notEmpty(),
|
||||
body('color', 'must be a string').notEmpty(),
|
||||
body('size', 'must be a number').isNumeric(),
|
||||
body('owner', 'must be a string').notEmpty(),
|
||||
body('appraisedValue', 'must be a number').isNumeric(),
|
||||
body('ID', 'must be a string').notEmpty(),
|
||||
body('Color', 'must be a string').notEmpty(),
|
||||
body('Size', 'must be a number').isNumeric(),
|
||||
body('Owner', 'must be a string').notEmpty(),
|
||||
body('AppraisedValue', 'must be a number').isNumeric(),
|
||||
async (req: Request, res: Response) => {
|
||||
logger.debug(req.body, 'Create asset request received');
|
||||
|
||||
|
|
@ -79,7 +78,7 @@ assetsRouter.post(
|
|||
}
|
||||
|
||||
const mspId = req.user as string;
|
||||
const assetId = req.body.id;
|
||||
const assetId = req.body.ID;
|
||||
|
||||
try {
|
||||
const submitQueue = req.app.locals.jobq as Queue;
|
||||
|
|
@ -88,10 +87,10 @@ assetsRouter.post(
|
|||
mspId,
|
||||
'CreateAsset',
|
||||
assetId,
|
||||
req.body.color,
|
||||
req.body.size,
|
||||
req.body.owner,
|
||||
req.body.appraisedValue
|
||||
req.body.Color,
|
||||
req.body.Size,
|
||||
req.body.Owner,
|
||||
req.body.AppraisedValue
|
||||
);
|
||||
|
||||
return res.status(ACCEPTED).json({
|
||||
|
|
@ -190,11 +189,11 @@ assetsRouter.get('/:assetId', async (req: Request, res: Response) => {
|
|||
assetsRouter.put(
|
||||
'/:assetId',
|
||||
body().isObject().withMessage('body must contain an asset object'),
|
||||
body('id', 'must be a string').notEmpty(),
|
||||
body('color', 'must be a string').notEmpty(),
|
||||
body('size', 'must be a number').isNumeric(),
|
||||
body('owner', 'must be a string').notEmpty(),
|
||||
body('appraisedValue', 'must be a number').isNumeric(),
|
||||
body('ID', 'must be a string').notEmpty(),
|
||||
body('Color', 'must be a string').notEmpty(),
|
||||
body('Size', 'must be a number').isNumeric(),
|
||||
body('Owner', 'must be a string').notEmpty(),
|
||||
body('AppraisedValue', 'must be a number').isNumeric(),
|
||||
async (req: Request, res: Response) => {
|
||||
logger.debug(req.body, 'Update asset request received');
|
||||
|
||||
|
|
@ -209,7 +208,7 @@ assetsRouter.put(
|
|||
});
|
||||
}
|
||||
|
||||
if (req.params.assetId != req.body.id) {
|
||||
if (req.params.assetId != req.body.ID) {
|
||||
return res.status(BAD_REQUEST).json({
|
||||
status: getReasonPhrase(BAD_REQUEST),
|
||||
reason: 'ASSET_ID_MISMATCH',
|
||||
|
|
@ -263,7 +262,7 @@ assetsRouter.patch(
|
|||
})
|
||||
.withMessage('body must contain an array with a single patch operation'),
|
||||
body('*.op', "operation must be 'replace'").equals('replace'),
|
||||
body('*.path', "path must be '/owner'").equals('/owner'),
|
||||
body('*.path', "path must be '/Owner'").equals('/Owner'),
|
||||
body('*.value', 'must be a string').isString(),
|
||||
async (req: Request, res: Response) => {
|
||||
logger.debug(req.body, 'Transfer asset request received');
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ const { BAD_REQUEST, INTERNAL_SERVER_ERROR, NOT_FOUND } = StatusCodes;
|
|||
export const createServer = async (): Promise<Application> => {
|
||||
const app = express();
|
||||
|
||||
// Remember for production usage, to check any TLS or CORS requirements
|
||||
|
||||
app.use(
|
||||
pinoMiddleware({
|
||||
logger,
|
||||
|
|
|
|||
Loading…
Reference in a new issue