C # -Clients für die Wargaming-API

    Die WG-API enthält eine sehr detaillierte Beschreibung der API, jedoch keine Bibliotheken für den Zugriff auf die API. Leider verwendet die API keinen der Standards, die automatisch Modelle und Methoden generieren könnten. Darüber hinaus konnten JSON-Antworten aufgrund der Struktur der Antwort keine Modelle generieren. Als Ergebnis stellte sich heraus, dass es einfacher war, Modelle (und insbesondere Methoden) manuell zu schreiben, aber diese Aktivität war sehr routinemäßig und langweilig. In diesem Artikel betrachten wir die Automatisierung der Erstellung von Modellen und Abfragemethoden aus der HTML-Beschreibung sowie die daraus resultierenden Vor- und Nachteile.

    Entwicklung


    Aufgrund der fehlenden Notwendigkeit habe ich keine Anwendungen im Kampf mit der WG-API, möchte diese API jedoch gleichzeitig als Beispiel für verschiedene Demos für den einfachen und offenen Zugriff auf Daten verwenden. Leider habe ich unter .NET keine Arbeitsbibliotheken für die WG-API gefunden und mein Dienstprogramm zum Generieren eines Clients in C # geschrieben, das die Dokumentation von der WG-API- Website liest und in vorgefertigte Anforderungs- und Antwortmodelle verarbeitet.

    Leider ist die WG-API-Dokumentation nicht vollständig und fehlerfrei An einigen Stellen ist es möglich zu verstehen, welche Antwort nur von der bereits mit JSON erhaltenen Antwort zurückgegeben wird.

    Später thunderspb habrozhitel schlugen einen viel einfacheren Weg vor, um das Datenschema zu erhalten, weshalb ich die Veröffentlichung des Artikels verschoben habe (fast zwei Monate aufgrund des akuten Zeitmangels). Leider hat dieses Datenschema auch genau die gleichen Nachteile - es gibt keine Möglichkeit, das Antwortformat für zusammengesetzte Datentypen zu verstehen. In Zukunft plane ich, das Dienstprogramm für die Arbeit mit diesem Datenschema zu erneuern, aber da die Arbeit mit der WG-API für mich derzeit keine Priorität darstellt, habe ich beschlossen, die derzeit implementierten Funktionen zu erläutern.

    Implementierung:


    Aufgrund der Tatsache, dass WG die Struktur dessen, was die Anforderung beim Verlassen ergibt, nicht vollständig dokumentiert, war es in der Praxis unpraktisch, das Format der Anforderung und der Antwort ein wenig zu gestalten. Am Ausgang erhalten wir so einfach wie eine einzelne Antwort, Sie können auch ein Array oder ein Wörterbuch erhalten. Wie oben erwähnt, können Sie herausfinden, was möglich ist, indem Sie eine Anfrage senden und eine Antwort in Form von JSON empfangen. In Live-Daten sehen Sie, wie die Daten zurückgegeben werden (es ist gut, dass die Dokumentation in jeder Methode einen Link zur Explorer-API hat, was dies ermöglicht Es ist sehr einfach, eine Anfrage zu stellen und die Antwort direkt im Browser anzuzeigen.)

    Am Ende haben wir eine sehr einfache Anwendung, bei der die Seiten mit der WG-API geöffnet und analysiert werden. Danach wird C # -Clientscode generiert und in einem separaten Fenster angezeigt:



    Den Quellcode können Sie hier herunterladen . Wenn Sie nicht möchten oder nicht die Möglichkeit haben, das Projekt herunterzuladen und auszuführen, können Sie dort auch ein Beispiel des generierten Client-Codes herunterladen .

    Anwendungsbeispiel:


    Der Quellcode für das folgende Beispiel kann hier verwendet werden .

    Wir haben einen Code, der mit PCL kompatibel ist, sodass wir diesen Code sowohl für Clientanwendungen als auch für Webserveranwendungen verwenden können.

    Zum Beispiel habe ich 15 Minuten damit verbracht, eine Xamarin Forms-Testanwendung ohne Design zu erstellen, in der ich im ersten Formular eine Suche nach Spitznamen und im zweiten Formular Informationen zu dem ausgewählten Spitznamen unter den gefundenen skizziert habe.

    Ich habe dem erstellten Projekt eine cs-Datei hinzugefügt, in die ich den von unserem Dienstprogramm generierten Code kopiert habe .

    Der nächste Schritt ist das Hinzufügen der Json.net-Bibliothek (Durchsuchen des Nugets nach der Newtonsoft.Json-Bibliothek oder des Befehls Install-Package Newtonsoft.Json über die Nuget-Konsole).

    Der Suchcode ist ganz einfach:

    var client = new WGClient.Client(); 
    var accounts = await client.SendRequestArray(new RequestWotAccountList() 
    { 
        ApplicationId = "demo", 
        Search = SearchNickname 
    }); 
    GamerAccounts = accounts; 
    

    Gleichzeitig haben wir dank der generierten Beschreibung die Möglichkeit, Eingabeaufforderungen direkt im Studio zu erhalten, wenn Sie den Code eingeben:



    Bitte beachten Sie, dass ApplicationId: "demo" nur zum Testen der API verwendet werden kann. Für die Veröffentlichung müssen Sie Ihre ApplicationId in Ihrem persönlichen Konto erstellen .

    Nun bleibt die Liste der gefundenen Spitznamen angezeigt:



    Leider habe ich mein Konto nicht mehr, danke Amir Sheriyev (mein Bruder) für die Angabe des Spitznamens für das Zerreißen von Teilen in den Beispielen.

    Öffnen Sie auf der Liste der gefundenen Konten das zweite Formular und übergeben Sie die ausgewählte Konto-ID:

    var item = e.SelectedItem as ResponseWgnAccountList; 
    Navigation.PushAsync(new DetailsPageView(item.AccountId)); 
    

    Auf der zweiten Seite wird auch eine Anforderung für eine andere Methode erstellt, um detailliertere Informationen zu erhalten:

    var client=new Client(); 
    var response=await client.SendRequestDictionary(new RequestWotAccountInfo() 
    { 
        ApplicationId = "demo", 
        AccountId = accountId 
    }); 
    



    Mit Hilfe unseres generierten Kunden haben wir die Möglichkeit, viel Zeit bei der Automatisierung der Routine zum Generieren der Anforderung und der Antwort auf die WG-API zu sparen und Zeit, Mühe und Aufmerksamkeit auf die Anwendung selbst zu richten.

    Nachteile:


    Die Notwendigkeit für manuelles Feilenschneiden


    Dies ist vielleicht der grundlegendste Nachteil - für die gesamte Antwort als Ganzes und für die Untertypen gibt es keine Informationen darüber, wie die Daten zurückgegeben werden (einfache Antwort, Array oder Wörterbuch). Daher müssen Sie an vielen Stellen Änderungen vornehmen.

    Nehmen Sie zum Beispiel die Technik-Methode ( Enzyklopädie / Fahrzeuge ).

    Um das Antwortvolumen zu reduzieren, filtern wir die Antwort nach der Technik einer Ebene und einer Nation. Das Aufrufen des folgenden Codes löst einen Fehler aus:

    var client = new WGClient.Client(); 
    var response = await client.SendRequestDictionary(new RequestWotEncyclopediaVehicles() 
    { 
        ApplicationId = "demo", 
        Tier = "8", 
        Nation = "ussr" 
    }); 
    



    Auslösen einer Ausnahme: Unbehandelte Ausnahme: Newtonsoft.Json.JsonSerializationException: Das aktuelle JSON-Array (z. B. [1,2,3]) kann nicht in den Typ 'WGClient.WorldOfTanks.WotEncyclopediaVehiclesCrew' deserialisiert werden, da für den Typ ein JSON-Objekt erforderlich ist (z. B. {"name" : "Wert"}), um die Deserialisierung korrekt durchzuführen.
    Um diesen Fehler zu beheben, ändern Sie entweder das JSON-Objekt in ein JSON-Objekt (z. B. {"name": "value"}) oder den deserialisierten Typ in ein Array oder einen Typ, der eine Erfassungsschnittstelle (z. B. ICollection, IList) wie List implementiert aus einem JSON-Array deserialisiert werden. JsonArrayAttribute kann dem Typ auch hinzugefügt werden, um die Deserialisierung aus einem JSON-Array zu erzwingen.

    Daraus folgt, dass der Crew-Subtyp nicht deserialisiert werden konnte und die Anforderung im API-Explorer erstellt wird, dann sehen wir, dass Crew als Array zurückgegeben wird:



    In diesem Fall wurde das Feld Engines korrekt erkannt, da der Typ des Feldes "Liste der ganzen Zahlen" dafür angegeben wurde, im Gegensatz zum Untertyp Crew, für den keine Informationen vorliegen.

    Sie können den Fehler beheben, indem Sie das Crew-Feld zu einem Array machen und das Feld ersetzen:

    /// 
    ///Экипаж 
    /// 
    [JsonProperty("crew")] 
    public WotEncyclopediaVehiclesCrew Crew { get; set; } 
    

    pro Array:

    public WotEncyclopediaVehiclesCrew[] Crew { get; set; } 
    

    Wir erhalten einen ähnlichen Fehler für default_profile.ammo, bzw. Sie müssen ihn auch dort beheben, indem Sie ein Array erstellen.

    Leider muss fast jede Methode solche Änderungen vornehmen, aber auch mit diesen Änderungen wird der Arbeitsaufwand erheblich verbessert.

    HTML-Abhängigkeit


    Da die WG-API keine JSON-Beschreibungsstandards verwendet, müssen Sie mit dem Parsen der HTML-Beschreibung zufrieden sein. Und HTML kann sich willkürlich ändern, und die Beschreibung der gleichen Typen kann sich unterscheiden und sogar auf Russisch gefunden werden, d. H. Es kann nicht garantiert werden, dass morgen kein neuer Name für den verwendeten Typ angezeigt wird.

    In der nächsten Version werden die Beschreibungen von JSON anstelle von HTML analysiert, und die Auswirkungen dieses Problems werden geringfügig abnehmen.

    Browser


    Die aktuelle Lösung basiert auf CefSharp, was bereits bedeutet, dass die Lösung nur auf der Win32-Plattform funktioniert. Sie können mithilfe von CefSharp-Bibliotheken neu schreiben, um eine plattformübergreifende Lösung zu erhalten. Wenn Sie wieder auf JSON-Parsing umsteigen, wird die CefSharp-Abhängigkeit beseitigt und eine Lösung erstellt, die unter Windows, Mac und Web funktioniert.

    Schlechtes Internet


    Der Parser berücksichtigt nicht, dass das Internet mit allen sich daraus ergebenden Konsequenzen verschwinden kann.

    Nicht optimale Client-API


    Am Ende entschied ich mich für eine ziemlich ausführliche und nicht sehr praktische Heavy-Version:

    SendRequest(TRequest request) 
    

    Es gibt unzählige Möglichkeiten, eine Lösung zu vereinfachen. Die einfachste Version der API kann jedoch erhalten werden, wenn WG nicht zu faul ist, um die Beschreibung der eigenen API abzuschließen (nämlich irgendwie zu regeln, was genau von der Anforderung als Antwort zu erwarten ist: ein Wörterbuch, ein Array oder ein einzelnes Objekt im Stamm- und untergeordneten Knoten der Antwort).

    Nuget oder die Notwendigkeit, die Json.NET-Bibliothek manuell hinzuzufügen


    Leider gibt es derzeit keine Möglichkeit, eine Lösung in Form einer Assembly oder eines Nuget-Pakets zu generieren, da aufgrund der oben beschriebenen Probleme (fehlende Beschreibung der Antwort auf die Anforderung) kein sofortiger Erhalt eines voll funktionsfähigen Codes möglich ist.

    Eine Lösung mit einem Nuget-Paket könnte die Notwendigkeit beseitigen, den Quellcode zu kopieren und Json.NET manuell zu verbinden, aber wie oben erwähnt, müssen Sie ihn an bestimmten Stellen ablegen.

    Testabdeckung


    Eine neue Version der API wird 1-2 mal im Monat veröffentlicht. Nachdem Sie die gesamte Antwort neu generiert haben, gehen automatisch alle Änderungen an der bereits vorgenommenen Datei verloren.

    Um sicherzustellen, dass in der neuen Version alles korrekt mit einer Datei geändert wurde, wäre es möglich, die erhaltene Lösung mit Tests abzudecken, um sicherzustellen, dass sie nicht vergessen haben, etwas mit einer Datei abzulegen. Tests können im Großen und Ganzen automatisch generiert werden. Theoretisch wird dadurch teilweise überprüft, ob die neue Version nicht alles vollständig kaputt macht.

    Codequalität


    Wie oben erwähnt, wurde der Code als Prototyp der Lösung geschrieben, was dann nicht schade wäre, ihn zu werfen und in eine funktionierende Version umzuschreiben. Insgesamt wurden einige Abende mit der gesamten Lösung verbracht (einschließlich eines in 15 Minuten geschriebenen Beispiels).

    Ein Projekt auswählen, um einen Kunden zu generieren


    Derzeit werden mehr als 40.000 Zeilen für alle Projekte gleichzeitig generiert. Man könnte eine Auswahl hinzufügen, welche Projekte und welche Methoden dieses Projekts der Client generieren muss.

    Momentan sind alle Projekte durch einen Namespace getrennt und Sie können das Projekt einfach löschen und dadurch die endgültige Baugruppengröße reduzieren.



    Das gleiche gilt für zusätzliche Felder.

    Sie können sich endlos verbessern, aber dies kann zusammengefasst werden.

    Zusammenfassung


    Die Tatsache, dass Wargaming versucht, für Entwickler offen zu sein und nicht nur die API zu öffnen, sondern auch die Feldwerte im Detail zu beschreiben, ist sehr lobenswert. Trotz erheblicher Mängel in der Beschreibung und in der Struktur der Antwort selbst (es ist nämlich unmöglich zu verstehen, was zurückgegeben wird, eine einzelne Antwort, ein Array oder ein Wörterbuch für komplexe Typen), ist dies eine der besten API-Dokumentationen für solche Dienste.

    Wie wir in diesem Artikel gesehen haben, kann WG auf einfache Weise Client-Bibliotheken für mindestens mehrere wichtige Programmiersprachen generieren, was den Entwicklern viel Zeit und Mühe ersparen kann, indem einfach eine vorgefertigte Bibliothek angeschlossen wird. Hoffen wir, dass wir ähnliche Lösungen von WG sehen werden.

    Jetzt auch beliebt: