Using a POST request for querying the Office Graph

Using a POST request for querying the Office Graph header image

In our session on Building Solutions with the Office Graph Waldek and I took some time to explain some of the queries we used for the Mavention apps that leverage the Office Graph. When working with the Office Graph you have to use the REST Search Interface to get results.

You can find a great article on Query Office Graph using GQL that helps you get started! All the samples you can find there are based on a GET query. The thing with a GET query is that an URL can only have a limited amount of characters. Depending on the browser and the server configuration the length may vary. The common consensus is that your URL should not exceed the 2,000 character mark. Having more complex Graph Queries you could easily top that character limit. So it would be a nice way to write Graph Queries as POST requests instead of a GET. You can find an overview on how to write your first REST post on SharePoint Search REST API Overview. It also contains a link to the QueryPropertyValueType enumeration that lists all options:

Member name | Description None | 0 StringType|1 Int32TYpe|2 BooleanType|3 StringArrayType|4 UnSupportedType|5

These different options are quite important when working with the different properties you need to set. Lets take a simple Graph Query and translate that to a POST request. Lets take the Graph Query that finds all items related to you and sorted by the last time they where modified:

https://<tenant\_address>/\_api/search/query?Querytext='*'&Properties='GraphQuery:ACTOR(ME),GraphRankingModel:{"features"\:[{"function"\:"EdgeTime"}]}'&SelectProperties='Docid,Title'&RankingModelId='0c77ded8-c3ef-466d-929d-905670ea1d72'&ClientType=GraphDemo

Translating that to a post request you will end up a request that contains the QueryText, Selected Properties and ClientType. As you should strive to be a good developer it would be a best practiced to add the ClientType to your queries. Besides that we add the Properties and provide the QueryPropertyValueTypeIndex based on the table above:

var postData = JSON.stringify({
    'request': {
        '__metadata': { 'type': 'Microsoft.Office.Server.Search.REST.SearchRequest' },
        'Querytext': '*',
        'SelectProperties': {
            'results': ['DocId', 'Title']
        },
        'ClientType': 'GraphDemo'
        'BypassResultTypes': 'true',
        'RowLimit': '5',
        'StartRow': '0',
        'RankingModelId': '0c77ded8-c3ef-466d-929d-905670ea1d72',
        'Properties': {
            'results': [
                {
                    'Name': 'GraphQuery',
                    'Value':
                    {
                        'StrVal': 'ACTOR(ME)'
                        'QueryPropertyValueTypeIndex': 1
                    }
                },
                {
                    'Name': 'GraphRankingModel',
                    'Value':
                    {
                        'StrVal': '{"features"\:[{"function"\:"EdgeTime"}]}'',
                        'QueryPropertyValueTypeIndex': 1
                    }
                }
            ]
        }
    }
});

By using the above snipped you would have a post request that is not bound by the character limit. This allows you to write more complex queries. Especially if you are trying to combine queries and get trending content from a specific location or specific type. You could easily replace the QueryText * with a more complex query. You could for instance use it to retrieve all trending learning materials using the query described in my session recap for the DIWUG on searching or finding.

When using the POST method you also need set-up the security correct. You need to pass on the X-RquestDigest header. You can find on Complete basic operations using SharePoint 2013 REST endpoints. So the final result of doing that POST will look like

$.ajax({
    url: appWebUrl + '/_api/search/postquery',
    method: 'POST',
    data: postData,
    headers: {
        'Accept': 'application/json;odata=nometadata',
        'Content-Type': 'application/json;odata=verbose',
        'X-RequestDigest': requestDigest
    }
}).success(function (data) {}

As you can see the POST request is a tad more work than just doing a GET. Yet setting it up correctly will save you trouble in the long run.

Loading comments…