Step-by-Step Guide: Consuming CubeMaster API with Azure
Learn how to integrate the CubeMaster API (https://api.cubemaster.net/loads
) using Azure with this detailed guide.
To use the CubeMaster API, you need an API key (TokenID) for authentication. Here's how to get started:
- Visit the CubeMaster website: https://cubemaster.net.
- Locate the "Sign In" option (typically found in the top-right corner).
- Fill out the registration form with your details (e.g., name, email, password, company information).
- After signing up, log in to your account dashboard.
- Navigate to the "Settings" - "Integration" section to generate your API key (TokenID).
- Generate an API key. Once generated, you’ll receive a unique
TokenID
(e.g.,abc123xyz789
). Copy this key and store it securely, as it will be used in the HTTP headers of your API requests. - Copy the TokenID and store it securely (e.g., in a configuration file or environment variable in your C# project).
Note: The TokenID will be used in the HTTP headers of your POST request for authentication.
A RESTful API (Representational State Transfer) is a way for programs to talk to each other over the internet using standard HTTP methods, like POST, GET, PUT, and DELETE. Here’s a simple breakdown:
- Endpoint: A specific URL (e.g.,
https://api.cubemaster.net/loads
) where the API listens for requests. -
HTTP Methods: Actions you can perform:
POST
: Send data to create something (e.g., building a load in CubeMaster).GET
: Retrieve data.
- Headers: Extra info sent with the request, like the TokenID for authentication.
- Body: The data you send (e.g., JSON with load details).
- Response: What the API sends back (e.g., success message or error).
In this guide, we’ll use the POST
method to send load data to the CubeMaster API and get a response with the calculated load plan.
We’ll use Azure Functions to call the CubeMaster API. Here’s how to set it up:
- Log in to the Azure Portal.
- Click the + Create a resource button (top-left corner).
- Search for Function App in the search bar, select it, and click Create.
-
In the creation form:
- Subscription: Choose your Azure subscription.
- Resource Group: Create a new one (e.g.,
CubeMasterIntegration
) or use an existing one. - Function App Name: Enter a unique name (e.g.,
CubeMasterFunction
). - Runtime Stack: Select
.NET
orNode.js
(we’ll use .NET in this guide). - Region: Choose a region close to you.
- Click Review + Create, then Create. Wait for deployment (takes a few minutes).
- Once deployed, go to your Function App in the Azure Portal by searching its name in the top search bar.
Assume your customer’s legacy database stores orders or shipments data (e.g., in SQL Server). We’ll fetch this data to build the API request.
- In the Azure Portal, go to your Function App.
- Click Functions in the left menu, then + Create to add a new function.
- Choose HTTP trigger template, name it (e.g.,
BuildLoad
), and set Authorization level to Function. Click Create. -
Connect to your legacy database:
- Go to Configuration in the left menu.
- Under Application settings, click + New application setting.
- Add a connection string (e.g.,
LegacyDBConnection
) with the value:Server=your-server;Database=your-db;User Id=your-user;Password=your-password;
. - Save the changes.
-
In the function code editor, fetch data using C# (example):
using System.Data.SqlClient; string connString = Environment.GetEnvironmentVariable("LegacyDBConnection"); using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); SqlCommand cmd = new SqlCommand("SELECT ItemName, Length, Width, Height, Weight, Quantity FROM Orders", conn); SqlDataReader reader = cmd.ExecuteReader(); // Process data into JSON structure (see Step 5) }
- Map fields like
ItemName
toName
,Quantity
toQty
, etc., to match the CubeMaster API request format.
Now, construct the POST request to https://api.cubemaster.net/loads
using the data from the legacy database and the provided JSON structure.
-
In your Azure Function (
BuildLoad
), add the following C# code to send the request:using System.Net.Http; using System.Text; [FunctionName("BuildLoad")] public static async Task
Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { var client = new HttpClient(); client.BaseAddress = new Uri("https://api.cubemaster.net/"); client.DefaultRequestHeaders.Add("TokenID", Environment.GetEnvironmentVariable("CubeMasterTokenID")); string jsonRequest = @"{ ""Title"": ""New Mixed Truck Load"", ""Description"": ""Hello Web API"", ""Cargoes"": [ { ""Name"": ""ITEM001"", ""Length"": 72, ""Width"": 30, ""Height"": 75, ""Weight"": 1002.45, ""OrientationsAllowed"": ""OrientationsAll"", ""TurnAllowedOnFloor"": false, ""Qty"": 16, ""ColorKnownName"": ""Brown"" }, { ""Name"": ""ITEM002"", ""Length"": 27.31, ""Width"": 37.5, ""Height"": 76.67, ""Weight"": 521.45, ""OrientationsAllowed"": ""OrientationsAll"", ""TurnAllowedOnFloor"": false, ""Qty"": 28, ""ColorKnownName"": ""Aqua"" }, { ""Name"": ""SKU0005"", ""Length"": 27.31, ""Width"": 9.5, ""Height"": 75.67, ""Weight"": 501.45, ""OrientationsAllowed"": ""OrientationsAll"", ""TurnAllowedOnFloor"": true, ""Qty"": 24, ""ColorKnownName"": ""Beige"" }, { ""Name"": ""SKU0005"", ""Qty"": 23 }, { ""Name"": ""SKU0008"", ""Qty"": 34 } ], ""Containers"": [ { ""VehicleType"": ""Dry"", ""Name"": ""53FT-Intermodal"", ""Length"": 630, ""Width"": 98, ""Height"": 106, ""ColorKnownName"": ""Blue"" } ], ""Rules"": { ""IsWeightLimited"": true, ""IsSequenceUsed"": false, ""FillDirection"": ""FrontToRear"", ""CalculationType"": ""MixLoad"" } }"; var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync("loads", content); string responseContent = await response.Content.ReadAsStringAsync(); return new OkObjectResult(responseContent); } -
Store the TokenID in Application settings:
- Go to Configuration > Application settings.
- Add
CubeMasterTokenID
with your API key from Step 1. - Save the changes.
- Click Save in the function editor to deploy the code.
Request JSON: The above code uses the exact request JSON provided, which specifies cargo items, a container, and rules for load building.
The CubeMaster API returns a detailed JSON response. Here’s how to process it:
-
Update your Azure Function to parse the response:
using Newtonsoft.Json; [FunctionName("BuildLoad")] public static async Task
Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { var client = new HttpClient(); client.BaseAddress = new Uri("https://api.cubemaster.net/"); client.DefaultRequestHeaders.Add("TokenID", Environment.GetEnvironmentVariable("CubeMasterTokenID")); string jsonRequest = @"..."; // Same as Step 5 var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync("loads", content); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { dynamic result = JsonConvert.DeserializeObject(responseContent); string status = result.status; string message = result.message; int cargoesLoaded = result.loadSummary.cargoesLoaded; double volumeLoaded = result.loadSummary.volumeLoaded; string diagramLink = result.filledContainers[0].graphics.images.path3DDiagram; log.LogInformation($"Status: {status}, Message: {message}, Cargoes Loaded: {cargoesLoaded}, Volume: {volumeLoaded}"); return new OkObjectResult(new { Status = status, Message = message, Diagram = diagramLink }); } else { log.LogError($"API Error: {response.StatusCode} - {responseContent}"); return new BadRequestObjectResult($"Error: {responseContent}"); } } -
Response JSON Example:
{ "status": "succeed", "message": "Engine created. 5 cargoes. 1 empty containers. Calculation started. Calculation ended. The load built successfully. The load saved to the cloud database.", "calculationError": "InvalidCargoSize", "document": { "title": "New Mixed Truck Load", "description": "Hello Web API", "isShared": true, "isAutoSaved": true, "isPending": false, "calculationTimeInSeconds": 0.6152743, "processId": "", "batchId": "", "createdBy": "CHANG@LOGEN.CO.KR", "createdAt": "2023-02-11T01:17:01.7392204+09:00", "updatedAt": "0001-01-01T00:00:00" }, "loadSummary": { "cargoesLoaded": 68, "piecesLoaded": 68, "cargoesLeft": 0, "piecesLeft": 57, "unitloadsLoaded": 0, "volumeLoaded": 5261723.4606, "weightLoaded": 42674.59999999999, "priceLoaded": 0, "containersLoaded": 1 }, "filledContainers": [ { "name": "#1 53FT-Intermodal", "sequence": 1, "loadSummary": { "cargoesLoaded": 68, "piecesLoaded": 68, "unitloadsLoaded": 0, "volumeLoaded": 5261723.4606, "volumeUtilization": 80.39990374424703, "vollumeUtilizationToLoadHeight": 81.03441853085657, "floorLoaded": 57090.75, "floorUtilization": 92.46963070942662, "weightLoaded": 42674.59999999999, "weightTotal": 42674.59999999999, "weightUtilization": 0, "dimWeight": 39424.33734939759, "priceLoaded": 0, "pricetUtilization": 0, "cargoesPerLayer": 14, "layersPerUnitload": 0 }, "graphics": { "images": { "path3DDiagram": "https://api.cubemaster.net/runtimes/b28413ca_51ed_44c9_b92e_13147363fd61.PNG", "pathComposite": "https://api.cubemaster.net/runtimes/7eb09974_2f1d_41bc_9371_2002658dce07.PNG" } } // ... (additional fields truncated for brevity) } ] // ... (additional fields truncated for brevity) }
- Extract key data like
status
,message
,cargoesLoaded
, andpath3DDiagram
for further use (e.g., display in a UI or store in a database).
Ensure your integration works smoothly by monitoring and debugging:
- In the Azure Portal, go to your Function App.
- Click Monitor in the left menu to view invocation logs.
- Check the Logs tab in the function editor for real-time output (e.g.,
log.LogInformation
messages). -
Enable Application Insights:
- Go to Application Insights in the left menu.
- Turn it on and link it to your Function App.
- Use the Insights dashboard to track request success/failure rates, response times, and errors.
- If an error occurs (e.g.,
InvalidCargoSize
in the response), review thecalculationError
field and adjust the request JSON (e.g., verify cargo dimensions). -
Test the function:
- Click Get function URL in the function editor.
- Use a tool like Postman to send a POST request to the URL with an empty body to trigger it.
Tip: Regularly check logs for issues like authentication failures (invalid TokenID) or network errors.