The WG API provides a very detailed description of the API, but does not provide any libraries for accessing the API. Unfortunately, the API does not use any of the standards that could automatically generate models and methods. In addition, JSON responses failed to generate models due to the nature of the response structure. As a result, it turned out that it was easier to write the models (and especially the methods) manually, but this exercise turned out to be very routine and boring. In this article, we consider the automation of creating a model and query methods from the HTML description, as well as the advantages and disadvantages obtained.
Development
Due to the lack of need, I have no applications in combat with the WG API, but at the same time I like to use this API as an example in various demonstrations for simple and open access to data. Unfortunately, I did not find a single working library under the WG API on .NET and I wrote my utility to generate a client in C #, which reads the documentation from the
WG API website and processes it into ready-made request and response models
Unfortunately, the WG API documentation is not complete and in some moments it is possible to understand which answer will be returned only from the already received response with JSON.
Later, the
thunderspb hacker suggested a much simpler way of obtaining a data scheme, which is why I postponed the publication of the article (almost two months due to an acute lack of time). Unfortunately, this data scheme has exactly the same drawbacks - there is no way to understand the response format for composite data types. In the future, I plan to remake the utility for working with this data scheme, but since currently the work with the WG API is not a priority for me, I decided to lay out what has been implemented so far.
')
Implementation:
Due to the fact that the WG does not document at all the structure of what the request will give out, it was necessary to make the request and response format a bit inconvenient in practice. At the output, we can get as just a single answer, you can also get an array or a dictionary. As mentioned above, it will be possible to find out what will be at the output only by sending a request and receiving a response in the form of JSON, where we will see live data, exactly how the data is returned (well, the documentation has a link to the API Explorer in each method that allows it's very easy to form a request and see the answer right in the browser).
In the end, we got a very simple application where the pages with the WG API are opened in turn and parsed. After that, C # client code is generated and displayed in a separate window:

Source code can be downloaded
here . If you do not want or can not download the project and run it, then there you can
download an example of the generated client code.
Usage example:
The source code of the example below can be collected here .We got code that is compatible with PCL, so we can use this code for both client applications and server-side web applications.
For example, I spent 15 minutes and created a test Xamarin Forms application without a design, where I sketched, in the first form, search by nickname, and in the second form, information about the selected nickname among those found.
In the created project I added a cs file, where I copied the
code generated by our utility.
The next step is to add the Json.net library (search the Newgetoft library's nuget in the library or the Install-Package Newtonsoft.Json command in the console nuget).
The search code is quite simple:
var client = new WGClient.Client(); var accounts = await client.SendRequestArray<ResponseWgnAccountList>(new RequestWotAccountList() { ApplicationId = "demo", Search = SearchNickname }); GamerAccounts = accounts;
At the same time, thanks to the generated description, we have the opportunity to receive hints right in the studio when typing the code:

Note that ApplicationId: “demo” can only be used for API testing. For the release, you must create your ApplicationId in your
accountNow it remains to display a list of found Nickname:
Unfortunately, I no longer have my account, thanks to Sheriyev Amir (my brother) for providing the game nickname for tearing apart in the examples.By tapu from the list of found, open the second form, transferring the selected AccountId:
var item = e.SelectedItem as ResponseWgnAccountList; Navigation.PushAsync(new DetailsPageView(item.AccountId));
The second page also creates a request to another method for more detailed information:
var client=new Client(); var response=await client.SendRequestDictionary<ResponseWotAccountInfo>(new RequestWotAccountInfo() { ApplicationId = "demo", AccountId = accountId });

Thus, with the help of our generated client, we have the opportunity to save a huge amount of time on automating the routine of forming the request and response to the WG API and focus time, effort and attention on the application itself.
Disadvantages:
The need for manual file finishing
Perhaps this is the main drawback - as for the answer as a whole, there is no information for the subtypes, as the data will be returned (a simple answer, an array or a dictionary). Therefore, in many places will have to make edits.
Take for example the Technique method (
encyclopedia / vehicles ).
To reduce the volume of the response, we filter the answer on the technique of one level and one nation. Calling the following code will cause an error:
var client = new WGClient.Client(); var response = await client.SendRequestDictionary<ResponseWotEncyclopediaVehicles>(new RequestWotEncyclopediaVehicles() { ApplicationId = "demo", Tier = "8", Nation = "ussr" });
Throwing an exception:
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Can not deserialize the current JSON array (eg [1,2,3]) into the 'WGClient.WorldOfTanks.WotEncyclopediaVehiclesCrew' type "}) To deserialize correctly.
JSON object for example: it would be possible to fix it. be deserialized from a JSON array. It is possible to deserialize from a JSON array.
It follows that the subtype Crew could not be deserialized, and if we build a query in
the Explorer API , we will see that Crew is returned as an array:

In this case, the Engines field was correctly recognized due to the fact that the field type “list of integers” was specified for it, unlike the subtype Crew, for which there is no information.
You can correct the error by making the Crew field an array, replacing the field:
///<summary> /// ///</summary> [JsonProperty("crew")] public WotEncyclopediaVehiclesCrew Crew { get; set; }
on array:
public WotEncyclopediaVehiclesCrew[] Crew { get; set; }
We get a similar error for default_profile.ammo; accordingly, it is also necessary to fix the array there.
Unfortunately, almost every method will have to make such changes, but nevertheless, even with these corrections, the amount of work is significantly improved.
HTML dependency
Since the WG API does not use any JSON description standards, one has to be content with parsing HTML descriptions. But HTML can change arbitrarily, and the description of the same types may differ and are even found in Russian, i.e. There are no guarantees that a new name for the type being used will not appear tomorrow.
In the next version I’m going to parse instead of HTML descriptions from JSON. And the effect of this problem will be slightly reduced.
Browser
The current solution is based on CefSharp, which already means that the solution will work only on the Win32 platform. Can be rewritten using CefSharp libraries to get cross-platform solution. Again, switching to JSON psing will eliminate CefSharp dependencies and make a solution that will work on Windows, Mac and Web.
Bad Internet connection
The parser does not take into account that the Internet can disappear with all the ensuing consequences.
Non-optimal client API
In the end, he stopped at a rather verbose and not very convenient heavy version:
SendRequest<TResponse>(TRequest request)
There are lots of ways to make a decision easier. But the simplest version of the API can be obtained if the company WG is not too lazy to finish the description of its own API (namely, to regulate how you can expect from the request as an answer: a dictionary, an array or a single object in the root and child response nodes).
Nuget or the need to manually add the Json.NET library
Unfortunately, at the moment there is no possibility to generate a solution in the form of an assembly or nuget package, since there is no possibility to immediately get a fully working code due to the problems described above (lack of description of the request response).
The solution with the Nuget package could eliminate the need to copy the source code and manually connect Json.NET, but as mentioned above, you will have to finish the file in some places.
Test coverage
1-2 times a month comes a new version of the API. Accordingly, having regenerated the entire answer, we will automatically lose all the edits by the file that we have already made.
In order to make sure that in the new version everything was correctly modified by the file, it would be possible to cover the obtained solution with tests in order to make sure that you did not forget to finish something with the file. By and large, one would automatically generate tests. In theory, this will allow to partially verify that the new version does not break everything at all.
Quality code
As mentioned above, the code was written as a prototype of the solution, which later would not be a pity to throw out and rewrite into a working version. The entire solution (including the example written in 15 minutes) was spent in total a couple of evenings.
Select a project to generate a client
Currently, more than 40 thousand lines are generated for all projects at once. It would be possible to add a choice of which projects and which methods of this project a client should be generated.
At the moment, all projects are separated by namespaces and you can simply delete the project and thereby reduce the final build size.

The same goes for extra margins.
You can endlessly engage in improvement, but this can be summed up.
Summary
The fact that Wargaming tries to be open to developers and tries not only to open the API, but also describes in detail the field values is very commendable. Despite significant shortcomings in the description and in the structure of the answer itself (namely, the fact that it is impossible to understand what will be returned, a single answer, an array or a dictionary for complex types), this is one of the best API documentation for such services.
As we saw from this article, WG could easily generate client libraries for at least several major programming languages, which could save a tremendous amount of time and effort for developers by simply connecting the finished library. Hopefully, we will see similar decisions from WG.