DebugCzęść NR.4 Potrafisz zbudować WEB API używając frameworka ASP.NET. Niestety to tylko początek. Po stworzenie WEB API musimy go przetestować. Wysyłać do niego żądania i sprawdzać wiadomości zwrotne
Istnieje parę narzędzi, które mogą ci pomóc w testowaniu twojego WEB API.
Sam przeglądarki mogą wysyłać żądanie GET. Istnieją dodatki do przeglądarki FireFox i Chrome, które potrafią wysłać żądania HTTP (GET,POST,PUT,DELETE). Zrobiłem o nich osobny wpis.
W tym wpisie skoncentruje się bardziej na narzędziu Fiddler.
Fiddler jest narzędziem do debugowania wywołań sieciowych. Analizuje on żądania HTTP i HTTPS pomiędzy komputerem, na którym jest uruchomiony Fiddler a serwerem wystawionym na zewnątrz.
Fiddler ma też funkcję budowy żądań do WEB API. Instalacja Fiddlera jest prosta. Muszę przyznać, że dużo się zmieniło od mojej ostatniej instalacji Fiddler. Widzę, że został on wykupiony przez firmę Telerik.
Fiddler jest .NET przyjaznym wynalazkiem i widać, że radzi on sobie z łapaniem przekazów z aplikacji Moder UI Windows 8.
Fiddler wygląda trochę przerażająco. Tona zakładek i przycisków. Od czego tutaj zacząć.
Może od przechwytywania ruchu związanego z naszymi API.
W poprzednich wpisach stworzyliśmy proste WEB API. Stworzymy teraz prostą aplikację wysyłającą żądanie do WEB API i prześledźmy ruch aplikacji używając Fiddler-a.
Konsolowa aplikacja do wysyłania żądania
Kliknij solucje prawym przyciskiem myszki i wybierz „Add->New Project”.
Z okna nowego projektu wybierz „Console Application”.
Postanowiłem zmodyfikować adres portu localhost projektu WEB API. W opcjach projektu w zakładce WEB zmień port na 4000.
W aplikacji konsolowe dodaje następujący kod. Klasa WebClient pobierze zawartość tekstową zwróconą przez serwer. Konsola będzie wykonywać to żądania, dopóki użytkownik nie wybierze klawisza „A”.
Zauważ, że do adres w zmiennej URI zawiera w sobie także specjalne odwołanie do Fiddlera. Fiddler domyślnie nie przechwytuje wywołań wykonanych przy pomocą klasy WebClient. Fiddler ma także problemy ze śledzeniem ruchu w adresie localhost, ale nie jest to zasada. Zależne jest to też od wersji Fiddler, jaką używasz.
Pamiętaj o porcie adresu do WEB API ja celowo zmieniłem go na 4000. Jeśli port będzie zły WebClient nic nie pobierze.
using System;
using System.Net;
namespace GameAPITester
{
class Program
{
static void Main(string[] args)
{
while (true)
{
string uri = "http://localhost.fiddler:4000/api/games/1234";
using (WebClient client = new WebClient())
{
Console.WriteLine(client.DownloadString(uri));
}
if (Console.ReadKey().Key == ConsoleKey.A)
break;
}
}
}
}
Jesteśmy prawie gotowi do testowania usługi. Musimy jeszcze ustalić kolejność uruchamiania projektu. Konsola jest bezużyteczna, jeśli lokalny serwer WEB API nie jest uruchomiony.
W poprzednim wpisie bardzo zmodyfikowałem WEB API. Do testowania będą potrzebne tylko podstawowe metody.
public class GamesController : ApiController
{
private static IList<Game> list = new List<Game>()
{
new Game(){Id = 1234,Name="Mortal Kombat"},
new Game(){Id = 1235,Name="Defender of Crown"},
new Game(){Id = 1236,Name="Shadow of The Beast"},
new Game(){Id = 1237,Name="Dune II"},
new Game(){Id = 1238,Name="The Settlers"}
};
// GET api/Games
[AcceptVerbs("GET")]
public IEnumerable<Game> AllGames()
{
return list;
}
[AcceptVerbs("GET", "POST")]
public Game RetriveGame(int id)
{
return list.First(e => e.Id == id);
}
// POST api/Games
[HttpPost]
public void AddGame(Game Game)
{
int maxId = list.Max(e => e.Id);
Game.Id = maxId + 1;
list.Add(Game);
}
// PUT api/Games/12345
[HttpPut]
public void UpdateGame(int id, Game Game)
{
int index = list.ToList().FindIndex(e => e.Id == id);
list[index] = Game;
}
// DELETE api/Games/12345
[HttpDelete]
public void DestroyGame(int id)
{
Game Game = RetriveGame(id);
list.Remove(Game);
}
}
Usunąłem także niepotrzebne schematy ścieżek do WEB API.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional,
}
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(
new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
}
}
Teraz możemy przejść do debugowania WEB API i klienta używając Fiddlera. Kompletny projekt z tego rozdziału możesz pobrać tutaj.
Działamy z Fiddler i łapiemy przekazy
Fiddler domyślnie śledzi wszystkie procesy. Co jest nie wygodne, jeśli masz otwarte wiele aplikacji generujący ruch sieciowi. Na dolnym lewym rogu możesz zobaczyć czy Fiddler rzeczywiście śledzi procesy i jak je filtruje.
Klikając na ikonę filtracji możesz zmienić listę aplikacji, które będą filtrowane. Opcja „Non-Browser” jest pożyteczna, ale możemy działać jeszcze lepiej.
Filtrowanie można ograniczyć do jednego procesu. Klikając na ikonkę tarczy strzelniczej i przeciągnij kursor na uruchomioną konsole.
Teraz będziesz mógł śledzić tylko proces aplikacji konsolowej.
Wybierając z listy interesującą nas zwrotkę jesteśmy w stanie przeanalizować zwróconą wiadomość.
W zakładce „Inspectors” możesz zobaczyć dane o zapytaniu, jak i o wiadomości zwrotnej. Przykładowo możesz podejrzeć jakie dane w formacie JSON zostały zwrócone przez WEB API.
Zakładka „Statistics” jak sama nazwa mówi w tej zakładce są statystyki działań żądań HTTP.
Tworzenie i wykonywania zapytania HTTP w Fiddler
Pamiętasz aplikację konsolową, którą przed chwilą stworzyliśmy. Nie będzie ona nam potrzebna.
Fiddler ma wbudowany mechanizm tworzenia żądań HTTP i my go użyjemy. Mechanizm ten znajduje się w zakładce „Composer”.
Przetestujmy wywołania POST na naszym WEB API. Wykonany tę metodę.
// POST api/Games
[HttpPost]
public void AddGame(Game Game)
{
int maxId = list.Max(e => e.Id);
Game.Id = maxId + 1;
list.Add(Game);
}
Uruchom WEB API. Do nagłówków określonych w Request Headers dopisz „Content-Type:application/json”.
Web API w ten sposób będzie wiedziało, że przesyłasz dane do niej w formacie JSON.
Do ciała zapytania określonego w oknie „Request-Body” napisz encję gry w formacie JSON. Oto przykład.
{"Id":1239,"Name":"Cannon Fodder"}
Naciśnij przycisk Request.
Do nagłówków zostanie dodany jeszcze „Content – Length”, który określa długość żądania Jest on automatycznie uzupełniany przez Fiddler.
Na liście powinna się pojawić nowa informacja o ruchu naszego żądania. Ma ono status 204, gdyż samo zapytanie nie zwróciło żadnej wiadomości zwrotnej.
Metoda post powinna dodać nową grę. Zmień metodę HTTP z POST na GET. Żądanie GET nie ma ciała dlatego Fiddler podkreśla ten obszar na czerwono. Nie będzie on użyty,
Klikając podwójnie na nową informację o ruchu żądania HTTP możesz zauważyć, że faktycznie gra została dodana do listy. U mnie nawet dwa razy, gdyż wywołałem żądanie POST dwa razy dla pewności.
Analogicznie możesz przetestować metody PUT i DELETE. Pamiętaj tylko o zmianie adresu URL.
Tak ja mówiłem w części pierwszej tego cyklu.To, co przesyłamy w ciele żądania jest później serializowane na obiekty klasy Game w C#.
Edit z 2022 roku : Kod projektu można pobrać tutaj : PanNiebieski/GameWebApiForBlogPost (github.com)