Making requests from code
In this section, we will consider making requests programatically to execute the following query:
query read_glas($cid : Int, $pagesize : Int){
useCompany(no: $cid) {
generalLedgerAccount(first: $pagesize) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
items {
accountNo
name
}
}
}
}
{
"data": {
"useCompany": {
"generalLedgerAccount": {
"totalCount": 344,
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "MA==",
"endCursor": "MjAw"
},
"items": [
{
"accountNo": 1000,
"name": "Forskning og utvikling"
},
{
"accountNo": 1020,
"name": "Konsesjoner"
},
{
"accountNo": 1030,
"name": "Patenter"
}
]
}
}
}
}
Important
The code for the example described here is available on GitHub at GraphQLSamples/SimpleQuery.
C# / .NET 5 Example
If you need to make requests programatically and are using C# and .NET 5, you can do the following:
-
Create a class to contain the actual query and potential variables.
class QueryRequest { [JsonPropertyName("query")] public string query { get; set; } [JsonPropertyName("variables")] public Dictionary<string, object> variables { get; set; } }
Note: The name of the C# class and its properties are not that important. However, the JSON text that is being sent in the body of the POST request must have the form shown in the following snippet (that contains a query for reading a first page of 100 records from the general ledger account table). Notice that
query
andvariable
must be in lower-case.{ "query": "query read_glas($cid : Int, $pagesize : Int){\r\n useCompany(no: $cid) {\r\n generalLedgerAccount(first: $pagesize) {\r\n totalCount\r\n pageInfo {\r\n hasNextPage\r\n hasPreviousPage\r\n startCursor\r\n endCursor\r\n }\r\n items {\r\n accountNo\r\n name\r\n }\r\n }\r\n }\r\n}", "variables": { "cid" : 9112233, "pagesize" : 100 } }
You can use JSON attributes (they are similar whether you use Json.NET or System.Text.Json) to ensure the serialized JSON document has the correct shape regarless of the names of the C# classes, properties, or fields.
-
Create classes to model the expected response, so that you can deserialize the JSON object returned by the server.
public class GeneralLedgerAccountResponse { public Data data { get; set; } } public class Data { public Usecompany useCompany { get; set; } } public class Usecompany { public GeneralLedgerAccountConnection generalLedgerAccount { get; set; } } public class GeneralLedgerAccountConnection { public int totalCount { get; set; } public PageInfo pageInfo { get; set; } public GeneralLedgerAccount[] items { get; set; } } public class PageInfo { public bool hasNextPage { get; set; } public bool hasPreviousPage { get; set; } public string startCursor { get; set; } public string endCursor { get; set; } } public class GeneralLedgerAccount { public int accountNo { get; set; } public string name { get; set; } }
-
Create a generic method that can execute a request and return the deserialized result.
class Program { private static readonly HttpClient _client = new(); private static async Task<TResponse> ExecuteQuery<TResponse>(QueryRequest request, string url, string accessToken) { try { _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); using var response = await _client.PostAsJsonAsync(url, request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadFromJsonAsync<TResponse>(); return content; } catch (HttpRequestException ex) { Console.Error.WriteLine($"{ex.Message} (code: {ex.StatusCode.Value})"); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } return default; } }
-
Obtain an access token programatically. This is covered in Examples for setting up authorization: .NET Code Sample.
-
Create a request string, execute it, and process the result.
class Program { static async Task Main(string[] args) { var url = "https://business.visma.net/api/graphql"; var accessToken = "..."; var companyId = ...; var pageSize = 100; var request = new QueryRequest() { query = @"query read_glas($cid : Int, $pagesize : Int){ useCompany(no: $cid) { generalLedgerAccount(first: $pagesize) { totalCount pageInfo { hasNextPage hasPreviousPage startCursor endCursor } items { accountNo name } } } }", variables = new Dictionary<string, object> { {"cid", companyId}, {"$pagesize", pageSize} } }; var result = await ExecuteQuery<GeneralLedgerAccountResponse>(request, url, accessToken); if (result?.data?.useCompany?.generalLedgerAccount?.items is object) { foreach (var gla in result.data.useCompany.generalLedgerAccount.items) { Console.WriteLine($"{gla.accountNo} - {gla.name}"); } } } }