Breaking Down CRM Rest builder Query.

Basic but neededIn this blog post i will break down the CRM rest builder query code line by line to help you understand what exactly happening in the piece of code.

This post is basically for the the people who are getting started with Dynamics 365 and also for those who did not care too much about what happening inside the code as long as it serve their purpose of retrieve/update/create etc.

Let’s get started. So I have generated a simple piece of code for retrieve request

var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v9.1/accounts(475b158c-541c-e511-80d3-3863bb347ba8)", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function() {
    if (this.readyState === 4) {
        req.onreadystatechange = null;
        if (this.status === 200) {
            var result = JSON.parse(this.response);
            var accountid = result["accountid"];
        } else {
            Xrm.Utility.alertDialog(this.statusText);
        }
    }
};
req.send();

XMLHttpRequest (XHR) objects are used to interact with servers. Here we are interacting Dynamics 365 servers.

1. XMLHttpRequest

 // Here we first create object of XMLHttpRequest
var req = new XMLHttpRequest();
 
2. Syntax : XMLHttpRequest.open(method, url,async)
XMLHttpRequest method open() initializes a 
newly-created request

GET - is a http reqeust method used to get data
url - the URL to send the request to the server
So here we are sending request to service root url
 [org name + /api/data/v9.1/]
Example
https://azuredevfordev.crm8.dynamics.com/api/data/v9.1/

You can find the service root URL in developer 
resources
This image has an empty alt attribute; its file name is capture.jpg

aync- optional Boolean parameter, defaulting to true,
indicating whether or not to perform the operation asynchronously. 

If not provide or set to true ->
 Code executes synchronously 

otherwise code will execute asynchronously
/* So here method is GET,
 url is 
https://azuredevfordev.crm8.dynamics.com/api/data/v9.1/
 async - is true i.e synchronous
*/ 

req.open("GET", Xrm.Page.context.getClientUrl() + 

"/api/data/v9.1/accounts(475b158c-541c-e511-80d3-3863bb347ba8)", true);
 

req.setRequestHeader

Okay got it so far but what’s happening here in req.setRequestHeader , I see a bunch of them

Here we are setting the HTTP request headers. But what are HTTP headers actually?

HTTP headers let the client and the server pass additional information with an HTTP request or response. An HTTP header consists of its case-insensitive name followed by a colon (:), then by its value.

Syntax 
XMLHttpRequest.setRequestHeader(header, value)

header - name of HTTP header
value - value of HTTP header

 setRequestHeader() sets the value of an HTTP request header. When using setRequestHeader(), you must call it after calling open(), but before calling send()

req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");

OData-MaxVersion – Clients SHOULD specify an OData-MaxVersion request header. If specified the service MUST generate a response with an OData-Version less than or equal to the specified OData-MaxVersion.
Header value states the maximum version of the protocol the client can accept in a response.

OData-Version -to specify the exact data service version. If both headers are present, precedence is given to OData-MaxVersion.

3. Content Negotiation Now we will talk about Content Negotiation

req.setRequestHeader("Accept", "application/json");

Generally, resources can have multiple presentations, mostly because there may be multiple different clients expecting different representations. Asking for a suitable presentation by a client, is referred as content negotiation.

Accept”, “application/json”

SyntaxAccept: <MIME_type>/<MIME_subtype>

application – Any kind of binary data that doesn’t fall explicitly into one of the other types

json – mime_subtype which specifies that client is excepting response in json format.

You can specify the other format like html,xml, etc

To determine what type of representation is desired at client side, HTTP header ACCEPT is used. For example here ,it simply means client is requesting data in Json format.

req.setRequestHeader("Accept", "application/json");

4. “Content-Type”, “application/json; charset=utf-8”

So Content-Type and Accept seems to be doing the
same thing. Is it so? 
No, let see how they are different
Accept: is what client is expecting.
Content-Type: is what format the actual data is in 
it's primarily
meant for put or post request However, strictly
speaking the specs 
itself does not rule out the possibility of HTTP GET
contains a payload 
https://tools.ietf.org/html/rfc7231#section-4.3.1

Content - type is Representation header field which
provide metadata about the representation.
When a message includes a payload body, 
the representation header fields describe
how to interpret the representation data enclosed
in the payload body

Also what does charset=utf-8  doing here?

Content-type: application/json; charset=utf-8 designates the content to be in JSON format, encoded in the UTF-8 character encoding.

5. “Prefer”, “odata.include-annotations=\”*\””

The Prefer request header field is used to 
indicate that particular server behaviors 
are preferred by the client but are not
required for successful completion of the request

What does odata.include-annotations=\”*\”” is doing here?

*” – represent all annotations

What happens when you retrieve a lookup field? You get a bunch of other values along with Guid

This is because we have include all annotations in the code. Now try with “-*”. You will get only Guid. This is because “-*” indicates no annotation.

Example of annotations

6. this.readyState

While we debug we get multiple values for this.readyState like 0,1,2,3,4 but have we tried to figure out what they actually represent?

this.readyState – property returns the state an XMLHttpRequest client is in

When it’s 4 state is DONE.

7. req.onreadystatechange

property defines a function to be executed when the readyState changes.

XMLHttpRequest.onreadystatechange = callback; callback is the function to be executed when the readyState changes.

8. this.state

HTTP response status codes indicate whether a specific HTTP request has been successfully completed.

9. this.response

response property returns the response’s body content as an ArrayBufferBlobDocument, JSON, or DOMString

10. req.send()

send() sends the request to the server. If the request is asynchronous (which is the default), this method returns as soon as the request is sent.

If the request is synchronous, this method doesn’t return until the response has arrived.

send() accepts an optional parameter which lets you specify the request’s body; this is primarily used for requests such as PUT.

References

  1. https://developer.mozilla.org/en-US/
  2. https://docs.microsoft.com/en-us/odata/webapi/include-annotations
  3. https://tools.ietf.org/html/rfc7231#section-4.3.1
  4. https://www.odata.org/documentation/