We've just demostrated the Model-First approach, starting with a model and generating APIs that expose that model. API First refers to doing things the other way round, starting with your API definition and building out the implementation.
Navigate to the API Endpoints page, http://localhost:8080/console/project/apidocs.
Click on the +API button to add an API.
Select the Welcome.json file in the Swagger folder or use the URL https://raw.githubusercontent.com/bladedancer/training/master/02_APIFirst/Swagger/Welcome.json
This API definition is just a contrived example. It has a single method on /welcome that takes the contact id and responds with some data.
Note: There are two save options, the Save and mock will create a sample flow for the methods in the API. This may be useful when you need to have working APIs for testing but the logic is not important.
In this case we'll just select Save as we'll be creating our flow.
The newly created endpoint is in a disabled state. This is because there are no flows associated with the methods.
To create the flow click on the Create Flow link.
Giving a step by step of dragging the pieces into place and renaming them would be tedious, so instead here's how the final flow should look.
This flow is centered around a query on the contact model. The endpoint will pass in the request parameters under $.params. These parameters are formated for use with the query and then the result is formatted and outputed to the response.
Type: Compose
Method: Format string
The model query method expects a where condition as a JSON encoded string. This node takes the cid value from the parameters and encodes it into a string that can be used as the where clause for the query.
The Compose node uses doT templates, see http://olado.github.io/doT/ for more detail. The template here is taking the cid and JSON stringifying it.
{"cid": {{=JSON.stringify(it.cid)}}}
Note also that the value of the evaluated template in the Next output is stored as $.where. This will be used as input for the query node.
Type: Conatact
Method: query
The model query node calls query. Here we are just going to pass a where value to select the contact.
Note that the next ouput is saving the result to $.models. The response from query will be an array of matching models (we'll be assuming at most 1).
Type: Condition
Method: Exists
As query returns an array we need to check if the array contains anything. One way of doing this is to check for the existence of the first element.
The test is checking for the existence of $.models[0], the first element in the array returned by Query Contact.
As this is just a simple example the False path just routes to the the Error node which we'll see later just returns a 400. However in a more real world scenario it would likely route to a different error node and return a 404.
Type: Compose
Method: Format object
The endpoint is defined as returning:
"schema": {
"type": "object",
"properties": {
"message": { "type": "string" },
"name": { "type": "string" }
}
}
The Format Response node is being used to create the data for the response. It's using the Compose node and a doT template to construct the return value.
The template is concatinating the contact's name details in to a single string:
{
"message": "Welcome",
"name": "{{?it.salutation}}{{=it.salutation}} {{?}}{{=it.firstname}} {{=it.lastname}}"
}
Note the Next output is saving the evaluated template as $.response, this will be used in the Success node.
Type: HTTP
Method: Set HTTP Response
This node allows us to set the values we want to use for the response. In this case we're returning a 200 status code with $.response as the body. Note the body is always application/json encoded.
Type: HTTP
Method: Set HTTP Response
This node allows us to set the values we want to use for the response. In this case we're returning a 400 status code to indicate a Bad Request error.
Save the flow, this will take you back to the API summary view. Expand the API should no longer be disabled. Expand the row and scroll to the Test API section. Try executing with a cid of batman. The response should be:
{
"message": "Welcome",
"name": "Mr. Bruce Wayne"
}