BIM for Owners – Using BIM 360 Field Equipment
Lab3 "Field API Web Intro"

Lab2 "Field API Intro"

(This is a continuation from the previous post: Lab1 “Hello Field World”.)

In Lab1, we learned how to obtain a ticket or authenticate, and got familiarized ourselves with the basics of REST call. In this lab, we retrieve a list of issues in a project. We then create a new issue.

To achieve this, we use the following services: 

  • /api/login (same as in the Lab1)
  • /fieldapi/admin/v1/project_names 
  • /fieldapi/issues/v1/list
  • /fieldapi/issues/v1/create 

Work Flow

The work flow of our little app is as follows:

  • Login – we first log in to the Field and obtains the ticket. We learned how to do this in the Lab1. 
  • Get a list of projects – we obtain a list of currently available projects. We keep one arbitrary project id to further get issues. 
  • Get a list of issues - from the given project, we obtain a list of issues. We take one arbitrary issue from the list, and keep the data for creating a new issue in the next step. 
  • Create an issue – create a new issue, using the issue data obtained in the previous step.

As an example, the application may look something like the following:

FieldAPILab2_2

Request and Response text boxes are added for our learning purpose.

Note: the chart at the lower portion of the dialog window is not a part of the Field API functionality by itself. We added this as an example. We will take a look at adding a simple chart as a bonus lab in Lab4. 

 

Project Names – Request

Get a list of project names and id’s.

URL: https://bim360field.autodesk.com/fieldapi/admin/v1/project_names

Supported Request Methods: POST

Required Parameters:

  • ticket

Doc:
https://bim360field.autodesk.com/apidoc/index.html#admin_api_method_3

ticket is from the response we received through the earlier Login request.


Project Names – Response

Here is the sample response for project_names:
[
  {
    "id":"d2338152-d859-429f-ae13-1859e7f77b00",
    "name":"Market One Project",
    "a360_project_id":null,
    "updated_at":"2014-10-23T19:13:24Z"
  },
  {
    "id":"7168264b-97dd-11e2-a4gb-02fg3afa57bd",
    "name":"Trial Sample - Power Plant",
    "a360_project_id":null,
    "updated_at":"2014-10-23T03:47:24Z"
  },
  {
    ... 
  }
]

For the specific context of our little app, we’ll be interested in id and name.

Note: there is another call /api/projects, which returns a list of projects with more detailed information about each project. We use project_names here in favor of its compactness in size.


Project Names – Sample Code

Here is the code sample to obtain a list of projects:

ProjectNames 
        public static List<Project> ProjectNames(string ticket)
        {
            // (1) Build request
            var client = new RestClient();
            client.BaseUrl = new System.Uri(_baseUrl);

            // Set resource or end point
            var request = new RestRequest();
            request.Resource = "/fieldapi/admin/v1/project_names";
            request.Method = Method.POST;

            // Add parameters
            request.AddParameter("ticket", ticket);

            // (2) Execute request and get response
            IRestResponse response = client.Execute(request);

            // Save response. This is to see the response for our learning.
            m_lastResponse = response;

            // (3) Parse the response and get the list of projects.
            
            if (response.StatusCode != HttpStatusCode.OK)
            {
                return null;
            }

            JsonDeserializer deserial = new JsonDeserializer();
            List<Project> proj_list = deserial.Deserialize<List<Project>>(response);

            return proj_list;
        }

 where Project is defined as follows: 

Project
    public class Project
    {
        public string id { get; set; }
        public string name { get; set; }
        public string a360_project_id { get; set; }
        public string updated_at { get; set; }
    }

Once you obtained a list of projects (proj_list), you can access project id and its name as follows: 

Project proj = proj_list[index];
string project_id = proj.id;
string project_name = proj.name;

Let's go to the Issue List request next. 

Issue List – Request

Issues/List returns a list of issues within a given project from the Field platform.

URL: https://bim360field.autodesk.com/fieldapi/issues/v1/list

Supported Request Methods: POST

Required Parameters:

  • ticket (obtained from login) 
  • project_id (obtained from the previoue call) 

Doc:
https://bim360field.autodesk.com/apidoc/index.html#issues_api_method_10

Known issues: There are following optional parameters mentioned in the document. However, we found that they are not functioning exactly as described at a moment:

  • area_ids
  • offset
  • limit

Issue List – Response

Here is the sample response for issues/list: 

[
  {
    "id":"14f2f005-6988-11e6-8afd-02dd3afa57bd",
    "created_by":"xiaodong.liang@autodesk.com",
    "fields":
      [
        {
          "id":"f--root_cause_id",
          "name":"Root cause",
          "display_type":"root_cause_id",
          "value":null
        },
        {
          "id":"f--location_detail",
          "name":"Location detail",
          "display_type":"text",
          "value":null
        },
        {
          "id":"f--issue_type_id",
          "name":"Issue type",
          "display_type":"issue_type_id",
          "value":"98f6738e-97ce-11e2-a4be-02cc3afa57bd"
        },
       {
          "id":"f--identifier",
          "name":"Identifier",
          "display_type":"text",
          "value":"XL-00005"},
        { 
          . . . 
        },

    ],
    "comments":[],
    "attachments":[]
  }
]


Issue List – Sample Code

Here is the code sample to obtain a list of issues:

IssueList
        public static List<Issue> IssueList(string ticket, string project_id, string area_ids, int offset=0, int limit=20)
        {
            // (1) Build request
            var client = new RestClient();
            client.BaseUrl = new System.Uri(_baseUrl);

            // Set resource or end point
            var request = new RestRequest();
            request.Resource = "/fieldapi/issues/v1/list"; // /fieldapi/ is prefered over /api/
            request.Method = Method.POST;

            // Add parameters
            request.AddParameter("ticket", ticket);
            request.AddParameter("project_id", project_id);

            // (2) Execute request and get response
            IRestResponse response = client.Execute(request);

            // Save response. This is to see the response for our learning.
            m_lastResponse = response;

            // (3) Parse the response and get the list of projects.

            if (response.StatusCode != HttpStatusCode.OK)
            {
                return null;
            }

            JsonDeserializer deserial = new JsonDeserializer();
            List<Issue> issue_list = deserial.Deserialize<List<Issue>>(response);

            return issue_list;
        }

where Issue is defined as the code below.

(Note also that we are not using optional parameters in this exercise because of the discrepancy of the result from what the documentation says. We hope it gets clarified near future.)    

Issue, IssueFieldItem 
    public class Issue
    {
        public string id { get; set; }
        public string created_by { get; set; }
        public List<IssueFieldItem> fields { get; set; }
        public List<Object> comments { get; set; }
        public List<Object> attachments { get; set; }
    }

    public class IssueFieldItem
    {
        public string id { get; set; }
        public string name { get; set; }
        public string display_type { get; set; }
        public string value { get; set; }
    }

 

Issue Create – Request

issues/create creates a new issue.

URL: https://bim360field.autodesk.com/fieldapi/issues/v1/create

Supported Request Methods: POST

Required Parameters:

  • ticket
  • project_id
  • issues

Doc:
https://bim360field.autodesk.com/apidoc/index.html#issues_api_method_11

issues is a string forming a JSON encoded array of issues. Each issue contains "fields" item which is an array of field identifiers and values pairs. 

The following shows an minimum example of an array with one issue: 

[{"temporary_id":"Q45","fields":[{"id":"f--description","value":"This is a test of creating an issue"},{"id":"f--issue_type_id","value":"f498d0f5-0be0-11e2-9694-14f6960d7e4f"}],"uri_references":[{"name":"Yahoo!","path":"http://www.yahoo.com"}]}]

or with line break for readability: 

[
  {
    "temporary_id":"Q45",
    "fields":
      [
        {"id":"f--description","value":"This is a test of creating an issue"},
        {"id":"f--issue_type_id","value":"f498d0f5-0be0-11e2-9694-14f6960d7e4f"}
      ],
      "uri_references":
      [
        {"name":"Yahoo!","path":"http://www.yahoo.com"}
      ]
  }
]


Issue Create – Response

Here is an example of successful issues/create response:

[
  {
    "temporary_id":"Tmp001",
    "id":"5784ddff-f6ad-48dd-9619-41a51ee0958c",
    "general_errors":[],
    "errors":[],
    "success":true
  }
]

Upon a successful request, you will see the value of "success" true in the response.  


Issue Create – Sample Code

Here is the code sample to create an issue:

IssueCreate
        public static string IssueCreate(string ticket, string project_id, string issues)
        {
            // (1) Build request
            var client = new RestClient();
            client.BaseUrl = new System.Uri(_baseUrl);

            // Set resource or end point
            var request = new RestRequest();
            request.Resource = "/fieldapi/issues/v1/create";  
            request.Method = Method.POST;

            // Add parameters
            request.AddParameter("ticket", ticket);
            request.AddParameter("project_id", project_id);
            request.AddParameter("issues", issues);

            // (2) Execute request and get response
            IRestResponse response = client.Execute(request);

            // Save response. This is to see the response for our learning.
            m_lastResponse = response;

            // (3) Parse the response and get the list of projects.

            if (response.StatusCode != HttpStatusCode.OK) { returnnull; }

            JsonDeserializer deserial = newJsonDeserializer();
            List<IssueCreateResponse> issueCreateResponse = deserial.Deserialize<List<IssueCreateResponse>>(response);
            
            return issueCreateResponse[0].id;
        }

    }

where IssueCreateResponse is defined as follows: 

IssueCreateResponse 
    public class IssueCreateResponse
    {
        public bool success { get; set; }
        public List<object> general_errors { get; set; }
        public List<object> errors { get; set; }
        public string id { get; set; }
        public string temporary_id { get; set; }
    }

 

Putting Together

Add UI’s to call ProjectNames(), IssueNames() and IssueCreate(). This can be of any form. For example, below shows how it looks like for our lab 2 sample application: 

buttonProject_Click, buttonIssue_Click, buttonIssueCreate_Click
        private void buttonProject_Click(object sender, EventArgs e)
        {

            List<Project> proj_list = Field.ProjectNames(m_ticket);

            ShowRequestResponse();

            // Post process to get hold of one project.
            // For simplicity, just pick up arbitrary one for our exercise.

            m_proj_index %= proj_list.Count;
            Project proj = proj_list[m_proj_index++];
            m_project_id = proj.id;
            string project_name = proj.name;
            labelProject.Text = "Project (" + m_proj_index.ToString() + "/" + proj_list.Count.ToString() + ")";
            textBoxProject.Text = project_name;

        }

        private void buttonIssue_Click(object sender, EventArgs e)
        {
            string area_ids = "No Area";
            List<Issue> issue_list = Field.IssueList(m_ticket, m_project_id, area_ids);
            m_issue_list = issue_list;

            ShowRequestResponse();

            // Post process to get hold of one project.
            // For simplicity, just pick up arbitrary one for our exercise.

            m_issue_index %= issue_list.Count;
            Issue issue= issue_list[m_issue_index++];
            m_issue_id = issue.id;
            IssueFieldItem item = issue.fields.Find(x => x.name.Equals("Identifier"));
            labelIssue.Text = "Issue (" + m_issue_index.ToString() + "/" + issue_list.Count.ToString() + ")";

            // Show the issue string
            JsonSerializer serial = new JsonSerializer();
            textBoxIssue.Text = serial.Serialize(issue);
            
            // Make one issue for creation. this is for later use.  
            textBoxNewIssue.Text = IssueToString(issue);
        }

        private void buttonIssueCreate_Click(object sender, EventArgs e)
        {
            string issues = textBoxNewIssue.Text;

            string issue_id = Field.IssueCreate(m_ticket, m_project_id, issues);

            ShowRequestResponse();

        }

Where IssueToString(issue)takes an issue obtained from IssueList() as an argument and format as an input for IssueCreate(). In  our simple app, we define a string for a new issue as a duplicate of the issue we obtained in the previous step. In reality, you will want to implement more elaborate UI to compose a new issue. 

Once again, the chart portion is not a part of Field API functionality. We will take a look later as bonus lab in Lab4.

You can download the Field API Intro Labs code from here

Next: Lab3 "Field API Web Intro"

Mikako  

Comments