Showing posts with label JSON. Show all posts
Showing posts with label JSON. Show all posts

XML vs. JSON for API requests and responses

XML is a document-centric data format and data processing language and stands for, "Extensible Markup Language".

JSON is a lighter-weight messaging-centric data format and stands for, "JavaScript Object Notation".

A question that often comes up in discussing APIs is whether an endpoint should accept and return JSON (increasingly the standard) instead of XML (was the old standard with XML-based SOAP services). If I have just 1 opinion to give, I would say that it is important for an API response model to be format agnostic (at least in regards to JSON vs. XML). Why not have the API accept and return both types and give clients the choice of either JSON or XML?

If your web service is so complex and has so much XML-specific dependencies, you may want to look into simplifying your model. None of the heavy lifting (of database communication, of data configuration and security information, data processing, etc.) should ever be done with dependencies from our sent and received XML and JSON GETs and POSTs.

That should be done on the server side, as much as is possible.


Here is an illustration from xml.com which describes the functionality equivalents in each format


In reality, if we model our program entities with easily understandable properties and no embedded config in the XML (this was the norm for SOAP), we will have no problem serializing our model objects into XML or JSON- losing no information in the process.


"XML is a data format, AND it is a language also. It has many powerful features that make it much more than a simple data format for data interchange. e.g., XPath, attributes and namespaces, XML schema and XSLT, etc. All these features have been the main reasons behind XML popularity.

JSON’s purpose is solely structured data interchange. It serves this purpose by directly representing objects, arrays, numbers, strings, and booleans. When meta-data and document markup is not a requirement, always use JSON." 
 -Lokesh Gupta


JSON vs. XML: A simple example

 {   
  "json": {   
   "myAppSettings": {   
   "appSettingDatabaseUri": "https://mysecuredatabaseserver.net"   
   }   
  }   
 }   
 <xml>  
 <myAppSettings>  
 <appSettingDatabaseUri>https://mysecuredatabaseserver.net</appSettingDatabaseUri>  
 </myAppSettings>  
 </xml>


It is a matter of preference for developers: For some, XML reads like a book and XML element structure and hierarchy makes for more easily understood data messages. For others, XML is overload, JSON is far more lightweight (ie. faster), and JSON is more readable (esp. for anyone knee-deep in NodeJS development where JSON is the default format for everything). JSON is also inherently parse-able with JavaScript. 

With XML it is not so. And XML's additional concerns (document media type mixing, security, channel bindings (remember WCF? 😅)), looping and various other other namespace and xsl/xslt configurations and transformations)- make it seem far more unwieldly than it actually is.

Aim for offering your API clients the option of JSON or XML for response type via "Accept: application/xml" or "Accept: application/json" header requests. Happy Parsing!

References: 

https://restfulapi.net/json-vs-xml

https://www.guru99.com/json-vs-xml-difference.html


History of XML

  • XML was also derived from SGML.
  • Version 1.0 of XML was released in February 1998.
  • Jan 2001:IETF Proposed Standard: XML Media Types
  • XML is the Extensible Markup Language.
  • 1970: Charles Goldfarb, Ed Mosher, and Ray Lorie invented GML
  • The development of XML started in the year 1996 at Sun Microsystem

History of JSON

  • Douglas Crockford specified the JSON format in the early 2000s.
  • The official website was launched in 2002.
  • In December 2005, Yahoo! starts offering some of its web services in JSON.
  • JSON became an ECMA international standard in 2013.
  • The most updated JSON format standard was published in 2017.

SSRS REST API v2

Here is a response from the SSSR REST API in action.. (you can access a lot more SSRS item properties and customize at will once you know the API)


The SSRS API v2 has far more functionality than v1, but they essentially work the same. You must be authenticated to the SSRS report server you are targeting (localhost in this case) to make web GET/POST requests to the API.

Once auth'd you can push and pull any useful SSRS data pretty easily to make SSRS do some pretty cool things it can't do out of the box..


This is the SSRS API as accessed through a web browser; simply give your .NET app an HttpClient and you can make use of all these responses; it's just JSON...



You can get a collection of SSRS catalog items as in the example above (folders, reports, KPIs) by just specifying the action name, or you can select an individual item by putting the item GUID in parenthesis in the API request URL:


You can access individual items in the API via GUID in parens after the API action name.




Common Useful SSRS API v2 Actions:
  • Reports
  • Datasets
  • Data Sources
  • Folders
  • Schedules
  • Subscriptions
  • Comments
  • KPIs
  • CatalogItems (everything)



Example of a .NET Standard library with an HttpService abstacting the SSRS API calls:
 namespace ExtRS  
 {  
   public class SSRSHttpService  
   {  
     const string ssrsApiURI = "https://localhost/reports/api/v2.0";  
     HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });  
         public async Task<GenericItem> GetReportAsync(Guid id)  
     {  
       client.BaseAddress = new Uri(ssrsApiURI + string.Format("/reports({0})", id));  
       var response = await client.GetAsync(client.BaseAddress);  
       var odata = response.Content.ReadAsStringAsync().Result;  
       return JsonConvert.DeserializeObject<GenericItem>(odata);  
     }  
   }  
 }  
This is verbose to better break down the steps of what is happening on the ExtRS service end




A very basic class designed to demonstrate using SSRS API Response to create a .NET object:
 using Newtonsoft.Json;  
 using System.Collections.Generic;  
 namespace ExtRS  
 {  
   public class GenericItem  
   {  
     [JsonProperty("@odata.context")]  
     public string ODataContext { get; set; }  
     [JsonProperty("Id")]  
     public string Id { get; set; }  
     [JsonProperty("Name")]  
     public string Name { get; set; }  
     [JsonProperty("Path")]  
     public string Path { get; set; }  
   }  
 }  
The power of the SSRS API is limited primarily your imagination- lots of customization can be made




And finally, called from a Controller Action in an MVC app:
 using System;  
 using System.Web.Mvc;  
 using System.Threading.Tasks;  
 using ExtRS;  
 namespace Daylite.Controllers  
 {  
   public class ReportsController : Controller  
   {  
     public SSRSHttpService service = new SSRSHttpService();  
     public async Task<ViewResult> GetReportsAsync()  
     {  
       return View("Index", await service.GetReportsAsync());  
     }  
     public async Task<ViewResult> GetFoldersAsync()  
     {  
       APIGenericItemsResponse result = await service.GetFoldersAsync();  
       return View("Index", result);  
     }  
     public async Task<ViewResult> GetReportAsync(Guid id)  
     {  
       GenericItem result = await service.GetReportAsync(id);  
       return View("Index", result);  
     }  
   }  
 }  


Reference: https://github.com/Microsoft/Reporting-Services/tree/master/APISamples


Newtonsoft JSON .NET Nuget Nugget

Most API payloads are in XML or JSON; it is best to know both of these data structures, and how to serialize/deserialize them

The JSON parsing utilities found in Newtonsoft.Json are very. very useful and should be common knowledge for any .NET developer who works with API data or anything producing or derived from JSON (JavaScript Object Notation).

In general, to use Newtonsoft.Json you simply need to create a .NET class hierarchy that mimics the structure and hierarchy of the target JSON. Once that is setup, serializing in-memory objects to JSON and deserializing the JSON back to in-memory objects is a breeze.

You achieve this by normal class hierarchy and making List<> of child objects, array properties, etc. Newtonsoft's 'JsonProperty' class property decorator maps JSON properties and the builtin serialization and deserialization methods facilitate working between JSON strings and the in-memory objects they represent.

The C# source code below demonstrates serialization from a SQL Server 2017 SSRS API v2 JSON response and then serializing that object back into JSON.

Source Code:

 using System;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 using Newtonsoft.Json;  
 using System.Collections.Generic;  
 using System.Net.Http;  
 using System.Threading.Tasks;  
 namespace DemoTests  
 {  
   [TestClass]  
   public class DemoTestJSON  
   {  
     [TestMethod]  
     public async Task TestDeserializeJSON()  
     {  
       HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });  
       client.BaseAddress = new Uri("http://localhost/reports/api/v2.0/reports");  
       var response = await client.GetAsync(client.BaseAddress);  
       var deserial = JsonConvert.DeserializeObject<APIGenericItemsResponse>(await response.Content.ReadAsStringAsync());       
       TestSerializeJSON(deserial);  
       Assert.IsNotNull(deserial);  
     }  
     [TestMethod]  
     public void TestSerializeJSON(APIGenericItemsResponse genericObject)  
     {      
       string serial = JsonConvert.SerializeObject(genericObject);  
       Assert.IsNotNull(null);  
     }  
   }  
   public class APIGenericItemsResponse  
   {  
     [JsonProperty("@odata.context")]  
     public string Context { get; set; }  
     [JsonProperty("value")]  
     public List<GenericItem> GenericItem { get; set; }  
   }  
   public class GenericItem  
   {  
     [JsonProperty("Id")]  
     public string Id { get; set; }  
     [JsonProperty("Name")]  
     public string Name { get; set; }  
     [JsonProperty("Path")]  
     public string Path { get; set; }  
   }  
 }  


SSRS API v2 /Reports JSON Response:




JSON Deserialization with Newtonsoft.Json:
The deserial variable holds an in-memory .NET object of type APIGenericResponse, derived (deserialized) from the SSRS API JSON response




JSON Serialization with Newtonsoft.Json:

The serial variable is simply the serialization APIGenericItemsResponse object serialized into a JSON string


Reference: https://www.newtonsoft.com/json/help/html/Introduction.htm