Testing the REST API - signavio/workflow-connector GitHub Wiki
You can test the deployment with a local sqlite database to make sure that the RESTful API is behaving properly. Alternatively, you can also use the workflow connector herokuapp at https://workflow-connector-test.herokuapp.com (using the HTTP Basic Authentication credentials, username: wfauser
, password: Foobar
) if you don't want to test on your own database just yet. The following sections demonstrate how to perform these tests on a local sqlite database.
Since everyone loves coffee
Let's assume we want to create a workflow that can instruct an intern on how to make coffee for the rest of our team. On a high level the intern would need to know what style of coffee we want, what the necessary ingredients are and how to properly use the machines to make the best batch of coffee possible. If we model these requirements in a database we could end up with a similar result as to whats depicted in the following diagramm.
Translating this diagramm to plain english would result in the following:
- A recipe contains instructions for the intern to follow. Making a recipe requires only one piece of equipment. A recipe of course contains many ingredients.
- A piece of equipment can be used in many different recipes.
- The database keeps track of the ingredients in stock in the
inventory
table. When the intern is shown the ingredients necessary for a recipe he or she will also be shown if there is enough of these ingredients in stock.
This database model has been translated one to one in the config/descriptor.json
file located in this repository.
Okay now on to the prerequisites
- Download and install sqlite
apt-get install sqlite
Populate the database
For testing purposes, we can execute the sqlite migration script provided in the build/migrate-to-sqlite.sh
to create our schema and populate it with some example data. The equipment table should end up looking like this:
Equipment
id | name | acquisition_cost | purchase_date |
---|---|---|---|
1 | Bialetti Moka Express 6 cup | 25.95000 | 2017-12-11 12:00:00 |
2 | Sanremo Café Racer | 8477.85000 | 2017-12-12 12:00:00 |
3 | Buntfink SteelKettle | 39.95000 | 2017-12-12 12:00:00 |
4 | Copper Coffee Pot Cezve | 49.95000 | 2017-12-12 12:00:00 |
Run the workflow connector
Before running the workflow-connector
command, either edit the config.yaml
file to include the database connection parameters and other settings, or export these settings as environment variables.
# Export environment variables
#
export PORT=:8080 DATABASE_URL=test.db DATABASE_DRIVER=sqlite3
#
# Run the connector
~/bin/workflow-connector
Listening on :8080
Exercise the REST API
Now we can test the functionality of the connector's REST API either in a new terminal, or using a javascript action in the Signavio Workflow Accelerator. The Workflow Connector's REST API aims to behave as any well crafted RESTful API should. A basic overview of REST can be found here. All HTTP requests are sent using HTTP basic auth with the default username (wfauser
) password (Foobar
) combination here.
Go ahead and fetch the equipment with id 1 by sending a HTTP GET
request to the connector using the curl
command (you can apt-get install curl
if curl
is not yet installed):
curl --verbose --header "Authorization: Basic $(echo -n "wfauser:Foobar" | base64)" --request GET http://localhost:8080/equipment/1
# Response:
## Headers
> GET /equipment/1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
> Authorization: Basic d2ZhdXNlcjpGb29iYXI=
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Fri, 23 Mar 2018 21:33:47 GMT
< Content-Length: 595
<
## Data
{
"acquisitionCost": {
"amount": 25.95,
"currency": "EUR"
},
"id": "1",
"name": "Bialetti Moka Express 6 cup",
"purchaseDate": "2017-12-11T12:00:00.000Z",
"recipes": []
}
Alternatively the same can be tested in a javascript action within workflow using the following javascript code.
Note: Make sure to replace the
host
variable with your configuration
const id = '1'
const host = 'http://localhost:8080'
const url = `${host}/equipment/${id}`
const auth = {
user: 'wfauser',
pass: 'Foobar'
}
const requestOptions = {auth: auth, url: url}
request.get(requestOptions, (error, response, body) => {
if (error) {
console.log(error)
return
}
if (response.statusCode > 399) {
console.log(new Error('Received an error status code'))
return
}
console.log(body)
})
// console.log output ->
{
"acquisitionCost": {
"amount": 25.95,
"currency": "EUR"
},
"id": "1",
"name": "Bialetti Moka Express 6 cup",
"purchaseDate": "2017-12-11T12:00:00.000Z",
"recipes": []
}
Insert a new equipment in the database
You can create a new product by sending a HTTP POST
to the appropriate route (here /equipment
). You will either receive a response containing the newly inserted equipment or an HTTP success status code 204 No Content
.
curl --verbose --header "Authorization: Basic $(echo -n "wfauser:Foobar" | base64)" --request POST --data 'name=Malt+mill+550&acquisitionCost=1270&purchaseDate=2016-09-04T11:00:00.000Z' http://localhost:8080/equipment
# Response:
## Headers
> POST /equipment HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
> Authorization: Basic d2ZhdXNlcjpGb29iYXI=
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 45
>
* upload completely sent off: 45 out of 45 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Fri, 23 Mar 2018 21:33:47 GMT
< Content-Length: 2
<
## Data
{
"acquistionCost": {
"amount": 1270,
"currency": "EUR"
},
"id": "5",
"name": "Malt mill 550",
"purchaseDate": "2016-09-04T11:00:00.000Z",
"recipes": []
}
And now using javascript
const host = 'http://localhost:8080'
const url = `${host}/equipment`
const auth = {
user: 'wfauser',
pass: 'Foobar'
}
const form = {
name: 'Malt mill 550',
acquisitionCost: 1270,
purchaseDate: '2016-09-04T11:00:00.000Z'
}
const requestOptions = {auth: auth, url: url, form: form}
request.post(requestOptions, (error, response, body) => {
if (error) {
console.log(error)
return
}
if (response.statusCode > 399) {
console.log(new Error('Received an error status code'))
return
}
console.log(body)
})
// console.log output ->
{
"acquisitionCost": {
"amount": 1270,
"currency": "EUR"
},
"id": "5",
"name": "Malt mill 550",
"purchaseDate": "2016-09-04T11:00:00.000Z",
"recipes": []
}
Updating an existing product
By sending a HTTP PATCH
to /equipment
you can change existing entries. Let's go ahead an adjust the name of the malt mill we just added recently.
curl --verbose --header "Authorization: Basic $(echo -n "wfauser:Foobar" | base64)" --request PATCH --data 'name=Malt+mill+400' http://localhost:8080/equipment/5
# Response:
## Headers
> PATCH /equipment/5 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
> Authorization: Basic d2ZhdXNlcjpGb29iYXI=
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 45
>
* upload completely sent off: 45 out of 45 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Fri, 23 Mar 2018 21:33:47 GMT
< Content-Length: 2
<
## Data
{
"cost": {
"amount": 1270,
"currency": "EUR"
},
"id": "5",
"name": "Malt mill 400",
"purchaseDate": "2016-09-04T11:00:00.000Z"
}
And again using javascript
const id = '5'
const host = 'http://localhost:8080'
const url = `${host}/equipment/${id}`
const auth = {
user: 'wfauser',
pass: 'Foobar'
}
const form = {
name: 'Malt mill 400'
}
const requestOptions = {auth: auth, url: url, form: form}
request.patch(requestOptions, (error, response, body) => {
if (error) {
console.log(error)
return
}
if (response.statusCode > 399) {
console.log(new Error('Received an error status code'))
return
}
console.log(body)
})
// console.log output ->
{
"acquisitionCost": {
"amount": 1270,
"currency": "EUR"
},
"id": "5",
"name": "Malt mill 400",
"purchaseDate": "2016-09-04T11:00:00.000Z",
"recipes": []
}
Deleting an existing product
We can delete existing entries in a table by sending a HTTP DELETE
to the /equipment/5
entry. We will then receive a 200 OK
HTTP status code back.
curl --verbose --header "Authorization: Basic $(echo -n "wfauser:Foobar" | base64)" --request DELETE http://localhost:8080/equipment/5
# Response:
## Headers
> DELETE /equipment/5 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
> Authorization: Basic d2ZhdXNlcjpGb29iYXI=
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 45
>
* upload completely sent off: 45 out of 45 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Fri, 23 Mar 2018 21:33:47 GMT
< Content-Length: 2
<
## Data
{
"status": {
"code": 200,
"description": "Resource with uniqueID '5' successfully deleted from equipment table"
}
}
And lastly using javascript
const id = '5'
const host = 'http://localhost:8080'
const url = `${host}/equipment/${id}`
const auth = {
user: 'wfauser',
pass: 'Foobar'
}
const requestOptions = {auth: auth, url: url}
request.delete(requestOptions, (error, response, body) => {
if (error) {
console.log(error)
return
}
if (response.statusCode > 399) {
console.log(new Error('Received an error status code'))
return
}
console.log(body)
})
// console.log output ->
{
"status": {
"code": 200,
"description": "Resource with uniqueID '4' successfully deleted from equipment table"
}
}