Skip to content

RESTful API

Dohun Kang edited this page May 22, 2020 · 37 revisions

Introduction

The users can use InFactory regardless of the development environment via RESTful API of InFactory. RESTful API is based on CRUD function on IndoorGML complex features. Users can create IndoorGML by writing their own indoor space information according to the predefined JSON(Javascript Object Notation) based form.

JSON format

All IndoorGML complex features can be represented by this JSON format. The details are described at JSON-format

How to use

First of all, the users need to implement their own client program which sends HTTP requests to the server. If there is no client program, it is recommended to use InSomnia, which is a debugging tool for RESTful API by by communicating HTTP request to the server program.

Insomnia

Quick Start

Terms

  • POST: Request to create a new entity including a document and the features in IndoorGML
  • GET: Retrieve information from InFactory server.
  • PUT: Request to update the existing entity. InFactory supports fully-patched Update.
  • DELETE: Request to remove a resource; however, the resource does not have to be removed immediately.

Coverage of this wiki

  • Quick start for POST, GET, PUT, DELETE
  • The form of the HTTP request including the form of url, body, and the response code.
  • The sample code based on HTML and Javascript. Copy and paste it at a blank file, save it, and open it.

1. How to run InFactory server

After installing Infactory as explained in Readme, you have to make InFactory server ready to receive the HTTP requests from your client.

$ mvn clean install
$ mvn jetty:run "-Djetty.port=9797"

2. Creating an IndoorGML Document

You can create an IndoorGML document by sending a set of HTTP requests to the InFactory server. The creation procedure is in general composed of the following steps;

  • Step 1: Creating IndoorGML document (POST request)
  • Step 2: Creating IndoorGML Features (POST request)
  • Step 3: Downloading IndoorGML document (GET request)

The detail for step 1 and 2 is described at the section 3.POST and the detail for step 3 is described at the section 4.GET.

3. POST

First of all, you have to give the name of IndoorGML document as a URL, for example, http://localhost:9797/documents/doc1. Although the users of InFactory do not need to care the sequence of feature creations and the IndoorGML class hierarchy, the key features shown in figure 1 should not be missing anyway.

IndoorFeatures
              |-> PrimalSpaceFeatures
                                    |-> CellSpace
                                    |-> CellSpaceBoundary
              |-> MultiLayeredGraph -> SpaceLayers -> SpaceLayer
                                                                |-> Nodes -> State
                                                                |-> Edges -> Transition

Figure 1. Basic IndoorGML Hierarchical Structure

When the users send GET request to the InFactory server, the server generates the IndoorGML document by arranging the hierarchical structure of the document.

3.1. Create Document

Before creating the features of IndoorGML, the users need to create the instance of IndoorGML document at the server of InFactory first. When the server of InFactory creats the IndoorGML document, the identifier of the document is needed. Usually the name of the IndoorGML document is used as the identifier of the document.

URL

http://{baseurl}/documents/{id}

  • {id} : alphanumeric id which starts as a alphabet
Example of the url
$ POST http://localhost:9797/documents/doc1
Response
  • Status : 201 CREATED / 404 NOT FOUND
  • Content-Type : None
Sample Code for Javascript
<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  var url = 'http://localhost:9797/documents/doc1';
  var contentType = 'application/json';
 var data = {
    "docId":"doc1"
}
  xhttp.open("POST", url, true);
  xhttp.setRequestHeader("Content-type", contentType);
  xhttp.send(JSON.stringify(data));
}
</script>

</body>
</html>
3.2. Create Indoorfeatures

After the instance of the IndoorGML document is created at the server of InFactory, the features including Indoorfeatures feature can be created. In this part, how to send the request for creating IndoorFeatures will be described. The other features such as PrimalSpaceFeatures and CellSpace can be created similar with creating Indoorfeatures. The example of creating those two types of features are also introduced at the section 3.3 and 3.4.

URL

https://{baseurl}/documents/{docId}/indoorfeatures/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Example of the url
$ POST http://localhost:9797/documents/doc1/indoorfeatures/lf1
Body
  • Content-Type : "application/json"
  • Accept : "application/json"
  • The content of the body
{
    "docId":"doc1", 
    "id":"lf1" 
}
Response
  • Status : 201 created / 404 NOT FOUND
  • Content-Type : None
3.3. Create PrimalSpaceFeatures
URL

https://{baseurl}/documents/{docId}/primalspacefeatures/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Example of the url
$ POST http://localhost:9797/documents/doc1/primalspacefeatures/psf1
Body
  • Content-Type : "application/json"
  • Accept : "application/json"
  • The content of the body
{
    "docId":"doc1",
    "parentId":"lf1",
    "id":"psf1"
}
Response
  • Status : 201 created / 404 NOT FOUND
  • Content-Type : None
3.4. Create CellSpace
URL

https://{baseurl}/documents/{docId}/cellspace/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Example of the url
$ POST http://localhost:9797/documents/doc1/cellspace/c1
Body
  • Content-Type : "application/json"
  • Accept : "application/json"
  • The content of the body
{
    "docId":"doc1",
    "parentId":"psf1",
    "id":"c1",
    "geometry": {
        "type" : "Solid",
        "coordinates" : "SOLID (( ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)), ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)), ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)) ))",
        "properties" : {
            "id" : "c1g",
            "type" : "wkt"
        }
    }
}
Response
  • Status : 201 created / 404 NOT FOUND
  • Content-Type : None
Sample code for Javascript
<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  var url = 'http://localhost:9797/documents/doc1/cellspace/c1';
  var contentType = 'application/json';
 var data = {
    "docId":"doc1",
    "parentId":"psf1",
    "id":"c1",
    "geometry": {
        "type" : "Solid",
        "coordinates" : "SOLID (( ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)), ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)), ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)) ))",
        "properties" : {
            "id" : "c1g",
            "type" : "wkt"
        }
    }
}
  xhttp.open("POST", url, true);
  xhttp.setRequestHeader("Content-type", contentType);
  xhttp.send(JSON.stringify(data));
}
</script>

</body>
</html>

4. GET

After creating the IndoorGML document, the users can download the document by the InFactory server. Or the users can get each features of IndoorGML elements. In this section, how to get the IndoorGML document and the single CellSpace features.

Example code of Javascript
<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 302) {
      console.log(this.responseText);
    }
  };
  var url = 'http://localhost:9797/documents/doc1/';
  var contentType = 'application/json';

  xhttp.open("GET", url, true);
  xhttp.setRequestHeader("Content-type", contentType);
  xhttp.send(0);
}
</script>

</body>
</html>
4.1. GET documents

When the users send this request to the InFactory server then the server return the XML document. If there is schema error at the data in the server, then the predefined error will be returned.

URL

https://{baseurl}/documents/{docId}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Body
  • Content-Type : None
  • Accept : None
Response
  • Status : 302 FOUND / 404 NOT FOUND
  • Content-Type : "application/xml"
<IndoorFeatures
    xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns="http://www.opengis.net/indoorgml/1.0/core"
    xmlns:navi="http://www.opengis.net/indoorgml/1.0/navigation"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" gml:id="lf1" xsi:schemaLocation="http://www.opengis.net/indoorgml/1.0/core http://schemas.opengis.net/indoorgml/1.0/indoorgmlcore.xsd http://www.opengis.net/indoorgml/1.0/navigation http://schemas.opengis.net/indoorgml/1.0/indoorgmlnavi.xsd">
    <gml:boundedBy xsi:nil="true"/>
    <primalSpaceFeatures>
        <PrimalSpaceFeatures gml:id="psf1">
            <gml:boundedBy xsi:nil="true"/>
            <cellSpaceMember>
                <CellSpace gml:id="c1">
                    <gml:boundedBy xsi:nil="true"/>
                    <cellSpaceGeometry>
                        <Geometry3D>
                            <gml:Solid gml:id="c1g">
                                <gml:exterior>
                                    <gml:Shell>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 0.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 0.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                        <gml:surfaceMember>
                                            <gml:Polygon>
                                                <gml:exterior>
                                                    <gml:LinearRing>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 0.0</gml:pos>
                                                        <gml:pos srsDimension="3">0.0 1.0 1.0</gml:pos>
                                                        <gml:pos srsDimension="3">1.0 1.0 1.0</gml:pos>
                                                    </gml:LinearRing>
                                                </gml:exterior>
                                            </gml:Polygon>
                                        </gml:surfaceMember>
                                    </gml:Shell>
                                </gml:exterior>
                            </gml:Solid>
                        </Geometry3D>
                    </cellSpaceGeometry>
                </CellSpace>
            </cellSpaceMember>
        </PrimalSpaceFeatures>
    </primalSpaceFeatures>
</IndoorFeatures>

Figure 2. the XML document received as the result of the GET request.

4.2. GET CellSpace

When the server of InFactory receives the request which asks the server to return the feature of IndoorGML, the server will return the data of the feature in the JSON format defined at JSON format.

URL

https://{baseurl}/documents/{docId}/cellspace/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Body
  • Content-Type : None
  • Accept : None
Response
  • Status : 302 FOUND / 404 NOT FOUND
  • Content-Type : "application/json"
{
    "docId":"doc1",
    "parentId":"psf1",
    "id":"c1",
    "geometry": {
        "type" : "Solid",
        "coordinates" : "SOLID (( ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)), ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)), ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)) ))",
        "properties" : {
            "id" : "c1g",
            "type" : "wkt"
        }
    }
}

Figure 3. The JSON data of the CellSpace feature received as the result of the request.

5. PUT

The server of InFactory fully updates the contents of the existing features when the server receives the request. The users need to write full content of the feature when the users send PUT request to the server.

Example code of Javascript
<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  var url = 'http://localhost:9797/documents/doc1';
  var contentType = 'application/json';
 var data = {
    "docId":"doc1"
}
  xhttp.open("PUT", url, true);
  xhttp.setRequestHeader("Content-type", contentType);
  xhttp.send(JSON.stringify(data));
}
</script>

</body>
</html>
URL

https://{baseurl}/documents/{docId}/cellspace/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Body
  • Content-Type : "application/json"
  • Accept : "application/json"
  • The content of the body
{
    "docId":"doc1",
    "parentId":"psf1",
    "id":"c1",
    "geometry": {
        "type" : "Solid",
        "coordinates" : "SOLID (( ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)), ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)), ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)) ))",
        "properties" : {
            "id" : "c1g",
            "type" : "wkt"
        }
    }
}
Response
  • Status : 201 CREATED / 404 NOT FOUND
  • Content-Type : None

6. DELETE

When the server of InFactory receives this request for deleting the document, then the document is deleted fully. If the server receives this request for deleting the feature in IndoorGML, then the feature is deleted fully. This example removes CellSpace "c1" at the server.

Example code with Javascript
<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  var url = 'http://localhost:9797/documents/doc1';
  var contentType = 'application/json';

  xhttp.open("DELETE", url, true);
  xhttp.setRequestHeader("Content-type", contentType);
  xhttp.send(0);
}
</script>

</body>
</html>
URL

https://{baseurl}/documents/{docId}/cellspace/{id}

  • {docId} : alphanumeric id which starts as a alphabet
  • {id} : alphanumeric id which starts as a alphabet
Body
  • Content-Type : None
  • Accept : None
Response
  • Status : 204 NO CONTENT / 404 NOT FOUND
  • Content-Type : None
Clone this wiki locally