Copyright © 2005-2024
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
Overview
This guide describes the RESTful API of the OpenWMS.org Movements module and its usage. Some general terms and definitions are explained and declared in the first part of the document whereas in the second part the usage of the API is shown in a more use-case-driven approach.
A description of all used API resources.
Representation Formats
Accept
header denotes the demanded type. Find the type in the examples below.
1. Dates in JSON
Date or datetime fields are not treated specially in JSON. Within the scope of this API a date or datetime field is always expected and
rendered as JSON String in ISO8601 format with timezone information and milliseconds: yyyy-MM-dd’T’HH:mm:ss.SSSTZD
.
2. Embedded Entities
For the sake of convenience some response entities may included embedded entities or even parts of it. A reference to the actual entity is provided as HAL link as well.
3. Error Responses
Beside the actual representation of resources, the server may result an error response in JSON format that contains basic information about the error occurred. This information is additional to the standard HTTP status code and may help clients to identify the error cause in order to re-phrase and send the request again.
Currently there are two types of errors with their own response formats.
3.1. Server Declined Errors
This kind of errors are sent by the server runtime environment even before the request had a chance to be processed.
An example response looks like this:
{
"timestamp": 1512400854941,
"status": 500,
"error": "Internal Server Error",
"exception": "org.ameba.oauth2.InvalidTokenException",
"message": "JWT expired at 2017-12-04T15:04:43Z. Current time: 2017-12-04T15:20:54Z, ...",
"path": "/v1/transport-units?bk=00000000000000004711"
}
The JSON structure contains the following fields.
Property Name | Description |
---|---|
timestamp |
When the error occurred on server side |
status |
The http status of the error |
error |
A short error text |
exception |
Internal class name of the Java exception type |
message |
A more descriptive error text describing the error in detail |
path |
The part of the URI for the REST resource that was queried |
3.2. API Declined Errors
Those errors are thrown within the REST API validation and processing logic. For example, if a client request does not match the expected format or has produced an error on server side, the API will decline the request and return a response with status client-side error (4xx).
The structure of the response is aligned to the RFC7808. An example response looks like this:
{
"message": "LocationGroup with name [NOT_EXISTS] not found",
"messageKey": "owms.common.common.lg.notFoundByName",
"obj" : [ "NOT_EXISTS" ],
"httpStatus" : "404",
"class" : "String"
}
The JSON structure contains the following fields.
Property Name | Description |
---|---|
message |
A short error text |
messageKey |
An unique identifier across the API that can be used to identify and translate the error message on the client side |
obj |
An array of possible passed arguments to the message |
httpStatus |
The http status of the error |
class |
The arguments type |
Following message keys are currently used:
Message Key | Description | Action |
---|---|---|
not.found |
The requested resource has not been found |
The resource does not exist anymore or has never existed. The resource identifier must be verified |
Resources
4. Index
The initial HTTP request to retrieve information about all available resources looks like the following. The Index page is a public available resource and does not need any authentication.
GET /index HTTP/1.1
Host: localhost:8080
The Index resource is returned in the response body with the response status of 200-OK. This main Index lists all primary resource entities to follow next.
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 111
{
"_links" : {
"movement-index" : {
"href" : "http://localhost:8080/v1/movements/index"
}
}
}
A client application must only know about the agreed link names and follow the corresponding href
link to navigate further.
5. Movements
A Movement
is a manual move of a TransportUnit
from a Location
A to Location
B. It always refers to a TransportUnit
and not to any
kind of material or articles. A Movement
has a source Location
where the TransportUnit
is picked up and may have a target
Location
or in general a target LocationGroup
where to bring the TransportUnit
to. A Movement
is meant to be executed by a human
user in manual warehouses with some kind of equipment, like a fork lift, a trolley etc. So the TransportUnit
is either on a Location
or
on the equipment - the latter is also expressed with a Location
. That said, a Movement
changed the source Location
where it is picked
up or dropped off but has no assignment to the human user. The operator/user may change, but the TransportUnit
is still assigned to the
Location
it is currently on.
5.1. Movement Index
The index with all possible operations on Movements
can be retrieved with a GET request:
GET /v1/movements/index HTTP/1.1
Host: localhost:8080
The response lists all the operations possible on Movements
with a name and the corresponding href link:
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 807
{
"_links" : {
"movement-create" : {
"href" : "http://localhost:8080/v1/transport-units/transportUnitBK/movements"
},
"movement-findAll" : {
"href" : "http://localhost:8080/v1/movements"
},
"movement-findForTuAndTypesAndStates" : {
"href" : "http://localhost:8080/v1/movements?barcode=transportUnitBK&types=INBOUND&states=state"
},
"movement-findForStateAndTypesAndSource" : {
"href" : "http://localhost:8080/v1/movements?state=state&source=source&types=INBOUND"
},
"movement-move" : {
"href" : "http://localhost:8080/v1/movements/pKey"
},
"movement-cancel" : {
"href" : "http://localhost:8080/v1/movements/pKey"
},
"movement-complete" : {
"href" : "http://localhost:8080/v1/movements/pKey/complete"
}
}
}
5.2. Create a Movement
To create a new Movement
a client needs to send a POST
request to Movements
sub resource of the primary
TransportUnits
resource with the data in the request body. The required data must contain the source where to
pick up the TransportUnit
and the target where to drop it off. The TransportUnit
that shall be moved is directly
referenced as the primary resource in the URI.
POST /v1/transport-units/4711/movements HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 120
Host: localhost:8080
{
"initiator" : "ERP",
"mode" : "AUTOMATIC",
"sourceLocation" : "WE_01",
"target" : "ERR_/0001/0000/0000/0000"
}
Path | Type | Description |
---|---|---|
|
|
(Optional) Initiator of the Movement, who ordered or triggered it |
|
|
(Optional) Whether the Movement should be directly processed (AUTOMATIC) or delayed (MANUAL) |
|
|
The source Location where the TransportUnit shall be picked up |
|
|
The target where to move the TransportUnit to |
If the Movement
has been created successfully, the server returns the URI to the created resource:
HTTP/1.1 201 Created
Location: http://localhost:8080/v1/transport-units/4711/movements/02f54d19-64e6-4535-9ee1-2d06a2eb45dc/
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 354
{
"ol" : 0,
"pKey" : "02f54d19-64e6-4535-9ee1-2d06a2eb45dc",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "ERP",
"mode" : "AUTOMATIC",
"priority" : 30,
"state" : "INACTIVE",
"sourceLocation" : "WE_01",
"sourceLocationGroupName" : "WE",
"target" : "ERR_/0001/0000/0000/0000",
"createdAt" : "2024-12-25T22:26:02Z"
}
Path | Type | Description |
---|---|---|
|
|
The persistent technical key of the Movement |
|
|
The business key of the TransportUnit to create |
|
|
The type of Movement |
|
|
Initiator of the Movement, who ordered or triggered it |
|
|
Whether the Movement should be directly processed (AUTOMATIC) or delayed (MANUAL) |
|
|
A priority how fast the Movement needs to be processed; A higher value means less prior than lower values |
|
|
The current state of the Movement |
|
|
The source Location where the TransportUnit shall be picked up |
|
|
The name of the LocationGroup the sourceLocation belongs to |
|
|
The target where to move the TransportUnit to |
|
|
Timestamp when the Movement has been created |
5.3. Find all Movements
An HTTP GET
request to the primary resource without any query parameters returns an array of all existing Movements
.
GET /v1/movements HTTP/1.1
Host: localhost:8080
Returns in this example an array of three Movements
or an empty array if none exist:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 1180
[ {
"ol" : 0,
"pKey" : "1000",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "POP::1",
"mode" : "MANUAL",
"sku" : "SKU-42",
"priority" : 30,
"state" : "INACTIVE",
"sourceLocation" : "HRL.10.20.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_01",
"startedAt" : "2024-12-25T22:26:02Z",
"latestDueAt" : "2024-12-25T22:26:02Z",
"finishedAt" : "2024-12-25T22:26:02Z",
"createdAt" : "2024-12-25T22:26:02Z"
}, {
"ol" : 0,
"pKey" : "1001",
"transportUnitBk" : "4712",
"type" : "OUTBOUND",
"initiator" : "SOP::1",
"mode" : "AUTOMATIC",
"priority" : 20,
"state" : "ACTIVE",
"sourceLocation" : "HRL.10.21.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_02",
"latestDueAt" : "2024-12-25T22:26:02Z",
"createdAt" : "2024-12-25T22:26:02Z"
}, {
"ol" : 0,
"pKey" : "1002",
"transportUnitBk" : "4713",
"type" : "REPLENISHMENT",
"initiator" : "UI",
"mode" : "AUTOMATIC",
"priority" : 20,
"state" : "DONE",
"sourceLocation" : "HRL.10.22.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_02",
"latestDueAt" : "2024-12-25T22:26:02Z",
"createdAt" : "2024-12-25T22:26:02Z"
} ]
5.4. Find Movements for a TransportUnit in States and of Types
An HTTP GET
request to the primary resource with additional query parameters is required to find Movements
in particular states
of
particular types
for a TransportUnit
identified by its barcode
.
GET /v1/movements?barcode=4711&types=INBOUND&states=INACTIVE HTTP/1.1
Host: localhost:8080
Parameter | Description |
---|---|
|
The business key of the TransportUnit to search for |
|
The Movement types to search for |
|
The Movement states to search for |
Returns an array of Movements
or an empty array:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 461
[ {
"ol" : 0,
"pKey" : "1000",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "POP::1",
"mode" : "MANUAL",
"sku" : "SKU-42",
"priority" : 30,
"state" : "INACTIVE",
"sourceLocation" : "HRL.10.20.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_01",
"startedAt" : "2024-12-25T22:26:03Z",
"latestDueAt" : "2024-12-25T22:26:03Z",
"finishedAt" : "2024-12-25T22:26:03Z",
"createdAt" : "2024-12-25T22:26:02Z"
} ]
Path | Type | Description |
---|---|---|
|
|
The persistent technical key of the Movement |
|
|
The business key of the TransportUnit to move |
|
|
The type of Movement |
|
|
Initiator of the Movement, who ordered or triggered it |
|
|
Whether the Movement should be directly processed (AUTOMATIC) or delayed (MANUAL) |
|
|
Refers to the demanded Product for that the Movement has been created |
|
|
A priority how fast the Movement needs to be processed; A higher value means less prior than lower values |
|
|
The current state of the Movement |
|
|
The source Location where the TransportUnit shall be picked up |
|
|
The name of the LocationGroup the sourceLocation belongs to |
|
|
The target where to move the TransportUnit to |
|
|
Timestamp when the Movement has been started |
|
|
Timestamp until when the Movement must be done |
|
|
Timestamp when the Movement has been finished |
|
|
Timestamp when the Movement has been created |
5.5. Find Movements in State of Types and at Source
An HTTP GET
request to the primary resource with additional query parameters is required to find Movements
in a particular state
, of
particular types
and at a given source
.
GET /v1/movements?state=DONE&types=INBOUND%2CREPLENISHMENT&source=STOCK HTTP/1.1
Host: localhost:8080
Parameter | Description |
---|---|
|
The Movement states to search for |
|
The Movement types to search for |
|
Either the source Location or the name of the source LocationGroup to search Movements for |
Returns an array of Movements
or an empty array:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 720
[ {
"ol" : 0,
"pKey" : "1002",
"transportUnitBk" : "4713",
"type" : "REPLENISHMENT",
"initiator" : "UI",
"mode" : "AUTOMATIC",
"priority" : 20,
"state" : "DONE",
"sourceLocation" : "HRL.10.22.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_02",
"latestDueAt" : "2024-12-25T22:26:03Z",
"createdAt" : "2024-12-25T22:26:02Z"
}, {
"ol" : 0,
"pKey" : "1002",
"transportUnitBk" : "4713",
"type" : "REPLENISHMENT",
"initiator" : "UI",
"mode" : "AUTOMATIC",
"priority" : 20,
"state" : "DONE",
"sourceLocation" : "HRL.10.22.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_02",
"latestDueAt" : "2024-12-25T22:26:03Z",
"createdAt" : "2024-12-25T22:26:02Z"
} ]
5.6. Move a Movement
An already existing Movement
can be moved from one Location
to another. The client needs to send a HTTP PATCH
request to the identified resource and pass a subset of a Movement
in the request body.
The request could look like this:
PATCH /v1/movements/1000 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 107
Host: localhost:8080
{
"transportUnitBk" : "4711",
"mode" : "AUTOMATIC",
"state" : "ACTIVE",
"sourceLocation" : "LOC2"
}
If the Movement
has been moved successfully, the server returns the updated representation of the Movement
as part
of the response body:
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 446
{
"ol" : 0,
"pKey" : "1000",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "POP::1",
"mode" : "MANUAL",
"sku" : "SKU-42",
"priority" : 30,
"state" : "ACTIVE",
"sourceLocation" : "LOC2",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_01",
"startedAt" : "2024-12-25T22:26:03Z",
"latestDueAt" : "2024-12-25T22:26:03Z",
"finishedAt" : "2024-12-25T22:26:03Z",
"createdAt" : "2024-12-25T22:26:02Z"
}
But if the Movement
to be moved is already completed the server rejects the operation and responds with:
HTTP/1.1 500 Internal Server Error
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 196
{
"message" : "Movement [1002] cant be moved it is already completed",
"messageKey" : "owms.wms.mov.mov.completedNotMoved",
"obj" : [ "1002" ],
"httpStatus" : "500",
"class" : "String"
}
5.7. Cancel a Movement
An existing Movement
can be cancelled by a client. Therefore a DELETE
request needs to be sent to the Movement
resource. Cancellation is not always supported and depends on the current state of the Movement
. In the standard
implementation a Movement
can only be cancelled if the state is not already CANCELLED
or higher, otherwise an
exception is thrown.
The request could look like this:
DELETE /v1/movements/1000 HTTP/1.1
Host: localhost:8080
If the Movement
has been cancelled, the server returns the order as part of the response body:
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 458
{
"ol" : 0,
"pKey" : "1000",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "POP::1",
"mode" : "MANUAL",
"sku" : "SKU-42",
"priority" : 30,
"state" : "CANCELLED",
"sourceLocation" : "HRL.10.20.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "WA_01",
"startedAt" : "2024-12-25T22:26:03Z",
"latestDueAt" : "2024-12-25T22:26:03Z",
"finishedAt" : "2024-12-25T22:26:02Z",
"createdAt" : "2024-12-25T22:26:02Z"
}
5.8. Complete a Movement
To complete a Movement
a client needs to explicitly send the COMPLETE
action along a POST
request to the
Movement
resource. This completes the Movement
and sets the target to the required target
that is passed from the
caller in the response body. If the Movement
has already been completed no changes are done.
A valid request looks like:
PATCH /v1/movements/1000/complete HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 99
Host: localhost:8080
{
"transportUnitBk" : "4711",
"mode" : "AUTOMATIC",
"state" : "ACTIVE",
"target" : "LOC2"
}
Whereas the server responds on success:
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 452
{
"ol" : 0,
"pKey" : "1000",
"transportUnitBk" : "4711",
"type" : "INBOUND",
"initiator" : "POP::1",
"mode" : "MANUAL",
"sku" : "SKU-42",
"priority" : 30,
"state" : "DONE",
"sourceLocation" : "HRL.10.20.2.0",
"sourceLocationGroupName" : "STOCK",
"target" : "LOC2",
"startedAt" : "2024-12-25T22:26:02Z",
"latestDueAt" : "2024-12-25T22:26:02Z",
"finishedAt" : "2024-12-25T22:26:02Z",
"createdAt" : "2024-12-25T22:26:02Z"
}