Copyright © 2005-2022

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

Basically JSON is used as representation format by default if not otherwise requested or mentioned below. XML format is supported for the index pages as well, but must be requested explicitly. Furthermore a vendor specific JSON format is used to represent resource representations. Therefore it’s absolutely required the 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.

Unresolved directive in 1-index.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/get-index/http-request.adoc[]

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.

Unresolved directive in 1-index.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/get-index/http-response.adoc[]

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:

Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/move-index/http-request.adoc[]

The response lists all the operations possible on Movements with a name and the corresponding href link:

Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/move-index/http-response.adoc[]

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 required 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. 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: 151
Host: localhost:8080

{
  "transportUnitBk" : "4711",
  "initiator" : "test",
  "mode" : "AUTOMATIC",
  "sourceLocation" : "WE_01",
  "target" : "ERR_/0001/0000/0000/0000"
}

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/3a7fed32-5d18-4807-9b64-3ee37b2ee2e0/
Content-Type: application/hal+json;charset=UTF-8
Content-Length: 353

{
  "ol" : 0,
  "pKey" : "3a7fed32-5d18-4807-9b64-3ee37b2ee2e0",
  "transportUnitBk" : "4711",
  "type" : "INBOUND",
  "initiator" : "test",
  "mode" : "AUTOMATIC",
  "priority" : 30,
  "state" : "ACTIVE",
  "sourceLocation" : "WE_01",
  "sourceLocationGroupName" : "WE",
  "target" : "ERR_/0001/0000/0000/0000",
  "createdAt" : "2022-08-18T14:25:25Z"
}

5.3. Find all Movements

A 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: 948

[ {
  "ol" : 0,
  "pKey" : "1000",
  "transportUnitBk" : "4711",
  "type" : "INBOUND",
  "initiator" : "POP::1",
  "mode" : "MANUAL",
  "priority" : 30,
  "state" : "INACTIVE",
  "sourceLocation" : "HRL.10.20.2.0",
  "sourceLocationGroupName" : "STOCK",
  "target" : "WA_01",
  "createdAt" : "2022-08-18T14:25:25Z"
}, {
  "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",
  "createdAt" : "2022-08-18T14:25:25Z"
}, {
  "ol" : 0,
  "pKey" : "1002",
  "transportUnitBk" : "4713",
  "type" : "OUTBOUND",
  "initiator" : "UI",
  "mode" : "AUTOMATIC",
  "priority" : 20,
  "state" : "DONE",
  "sourceLocation" : "HRL.10.22.2.0",
  "sourceLocationGroupName" : "STOCK",
  "target" : "WA_02",
  "createdAt" : "2022-08-18T14:25:25Z"
} ]

5.4. Find Movements

A HTTP GET request to the primary resource with additional query parameters is required to find Movements in a particular state, type and source.

Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/order-find-all/http-request.adoc[]

Returns an array of Movements or an empty array:

Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/order-find-all/http-response.adoc[]

5.5. 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: 343

{
  "ol" : 0,
  "pKey" : "1000",
  "transportUnitBk" : "4711",
  "type" : "INBOUND",
  "initiator" : "POP::1",
  "mode" : "MANUAL",
  "priority" : 30,
  "state" : "ACTIVE",
  "sourceLocation" : "LOC2",
  "sourceLocationGroupName" : "STOCK",
  "target" : "WA_01",
  "startedAt" : "2022-08-18T14:25:25Z",
  "createdAt" : "2022-08-18T14:25:25Z"
}

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.6. 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: 356

{
  "ol" : 0,
  "pKey" : "1000",
  "transportUnitBk" : "4711",
  "type" : "INBOUND",
  "initiator" : "POP::1",
  "mode" : "MANUAL",
  "priority" : 30,
  "state" : "CANCELLED",
  "sourceLocation" : "HRL.10.20.2.0",
  "sourceLocationGroupName" : "STOCK",
  "target" : "WA_01",
  "finishedAt" : "2022-08-18T14:25:25Z",
  "createdAt" : "2022-08-18T14:25:25Z"
}

5.7. 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.

A valid request looks like: Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/move-complete/http-request.adoc[]

Whereas the server responds on success: Unresolved directive in 2-movements.adoc - include::/home/runner/work/org.openwms.tms.movements/org.openwms.tms.movements/target/generated-snippets/move-complete/http-response.adoc[]