issuetracker
============
To repozytorium zawiera przykładowe API użyte w książce.

# Implementacja
To jest API hipermediów przeznaczone do zarządzania zgłoszeniami błędów. Za jego pomocą można pobierać, tworzyć, modyfikować i zmieniać stan zgłoszeń błędów. Zostało zaimplementowane z użyciem ASP.NET Web API. Więcej informacji szczegółowych dotyczących projektu i implementacji znajdziesz [tutaj] (http://chimera.labs.oreilly.com/books/1234000001708/ch07.html)

# Wypróbuj
To API zostało umieszczone w chmurze [Azure] (http://azure.net). Poniżej przedstawiłem nieco informacji pokazujących sposób poruszania się po API. Takie samo podejście możesz zastosować w przypadku API działającego lokalnie, wtedy zastąp główny adres URL adresem lokalnym komputera oraz wykorzystaj zwracane łącza zamiast łączy Azure. (Oto wartość hipermediów :-) )

Warto pamiętać o jednym. Ponieważ mamy do czynienia z pojedynczym egzemplarzem działającym w chmurze, więc istnieje prawdopodobieństwo otrzymania innych wyników, gdy jednocześnie więcej osób będzie korzystać z API. Jednak informacje o stanie są przechowywane w pamięci i po kilku minutach braku aktywności witryna jest usypiana, dane zerowane do postaci przedstawionej poniżej.

## Punkt wyjścia
Przede wszystkim należy przejść do głównego punktu wyjścia wydając poniższe polecenie:

```text
curl -H "accept:application/vnd.collection+json" http://webapibook-issuetracker.azurewebsites.net/issue
```

Wartością zwrotną będzie lista zgłoszeń błędów:

```javascript
{
  "collection": {
    "href": "http://webapibook-issuetracker.azurewebsites.net:80/issue",
    "links": [
      {
        "rel": "profile",
        "href": "http://webapibook.net/profile"
      }
    ],
    "items": [
      {
        "href": "http://webapibook-issuetracker.azurewebsites.net/issue/1",
        "data": [
          {
            "name": "Description",
            "value": "To jest zgłoszenie błędu"
          },
          {
            "name": "Status",
            "value": "Open"
          },
          {
            "name": "Title",
            "value": "Zgłoszenie błędu"
          }
        ],
        "links": [
          {
            "rel": "http://webapibook.net/profile#transition",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/1?action=transition"
          },
          {
            "rel": "http://webapibook.net/profile#close",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/1?action=close"
          }
        ]
      },
      {
        "href": "http://webapibook-issuetracker.azurewebsites.net/issue/2",
        "data": [
          {
            "name": "Description",
            "value": "To jest inne zgłoszenie błędu"
          },
          {
            "name": "Status",
            "value": "Closed"
          },
          {
            "name": "Title",
            "value": "Inne zgłoszenie błędu"
          }
        ],
        "links": [
          {
            "rel": "http://webapibook.net/profile#transition",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=transition"
          },
          {
            "rel": "http://webapibook.net/profile#open",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=open"
          }
        ]
      }
    ],
    "queries": [
      {
        "rel": "http://webapibook.net/profile#search",
        "href": "/issue",
        "prompt": "Wyszukiwanie zgłoszenia błędu",
        "data": [
          {
            "name": "SearchText",
            "prompt": "Tekst do dopasowania w polach Title i Description"
          }
        ]
      }
    ],
    "template": {
      "data": [
        {
          "name": "Description",
          "prompt": "Opis zgłoszenia błędu"
        },
        {
          "name": "Status",
          "prompt": "Stan zgłoszenia błędu (otwarte lub zamknięte)"
        },
        {
          "name": "Title",
          "prompt": "Tytuł zgłoszenia błędu"
        }
      ]
    }
  }
  ```
## Pobieranie określonego zgłoszenia błędu
Zwróć uwagę, że pierwsze zgłoszenie błędu (`issue`) jest w stanie otwartym. Jeżeli chcesz pobrać informacje szczegółowe, wykorzystaj jego element `href`.

```text
curl http://webapibook-issuetracker.azurewebsites.net/issue/1
```

Wartością zwrotną są informacje szczegółowe w formacie JSON.

```javascript
{
  "id": "1",
  "title": "Zgłoszenie błędu",
  "description": "To jest zgłoszenie błędu",
  "status": "Open",
  "links": [
    {
      "rel": "self",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issue/1"
    },
    {
      "rel": "http://webapibook.net/profile#transition",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/1?action=transition",
      "action": "transition"
    },
    {
      "rel": "http://webapibook.net/profile#close",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/1?action=close",
      "action": "close"
    }
  ]
}
```
## Wyszukiwanie danych
Istnieje również możliwość wyszukania konkretnego zgłoszenia błędu. Jeżeli spojrzysz na szablon w pierwszej odpowiedzi Collection+JSON, możesz dostrzec ciąg tekstowy zapytania.

```javascript
"queries": [
  {
    "rel": "http://webapibook.net/profile#search",
    "href": "/issue",
    "prompt": "Wyszukiwanie zgłoszenia błędu",
    "data": [
      {
        "name": "SearchText",
        "prompt": "Tekst do dopasowania w polach Title i Description"
      }
    ]
  }
]
```

Zapytania CJ dostarczają parametry przekazywane w adresie URI jako część ciągu tekstowego zapytania. W omawianym przykładzie widzać, że `href` znajduje się w zasobie `issue` i istnieje parametr zapytania 'SearchText'. Poniżej pokazałem jak można wyszukać drugie zgłoszenie błędu. Wynikiem zapytania jest dokument CJ.

```text
curl -H "accept:application/vnd.collection+json" http://webapibook-issuetracker.azurewebsites.net/issue?searchtext=inne
```

Otrzymamy dokument CJ wraz ze zgłoszeniem błędu, w którego opisie znajduje się "To jest inne zgłoszenie błędu".

```javascript
{
  "collection": {
    "href": "http://webapibook-issuetracker.azurewebsites.net:80/issue?searchtext=inne",
    "links": [
      {
        "rel": "profile",
        "href": "http://webapibook.net/profile"
      }
    ],
    "items": [
      {
        "href": "http://webapibook-issuetracker.azurewebsites.net/issue/2",
        "data": [
          {
            "name": "Description",
            "value": "To jest inne zgłoszenie błędu"
          },
          {
            "name": "Status",
            "value": "Closed"
          },
          {
            "name": "Title",
            "value": "Inne zgłoszenie błędu"
          }
        ],
        "links": [
          {
            "rel": "http://webapibook.net/profile#transition",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=transition"
          },
          {
            "rel": "http://webapibook.net/profile#open",
            "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=open"
          }
        ]
      }
    ],
    "queries": [
      {
        "rel": "http://webapibook.net/profile#search",
        "href": "/issue",
        "prompt": "Wyszukiwanie zgłoszenia błędu",
        "data": [
          {
            "name": "SearchText",
            "prompt": "Tekst do dopasowania w polach Title i Description"
          }
        ]
      }
    ],
    "template": {
      "data": [
        {
          "name": "Description",
          "prompt": "Opis zgłoszenia błędu"
        },
        {
          "name": "Status",
          "prompt": "Stan zgłoszenia błędu (otwarte lub zamknięte)"
        },
        {
          "name": "Title",
          "prompt": "Tytuł zgłoszenia błędu"
        }
      ]
    }
  }
}
```
## Użycie łącza akcji
Teraz zobaczysz jak zmienić stan zgłoszenia błędu za pomocą hipermediów (łącza akcji). To zgłoszenie ma przypisany stan zamknięte (`closed`). Możesz je otworzyć przez przekazanie akcji `open` w łączu `href`:

```javascript
"links": [
    {
      "rel": "http://webapibook.net/profile#transition",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=transition"
    },
    {
      "rel": "http://webapibook.net/profile#open",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=open"
    }
  ]
```

Wydaj następujące polecenie:

```text
curl -d '' http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=open
```

Wprawdzie nie otrzymasz odpowiedzi, ale sprawdzenie stanu zgłoszenia błędu potwierdzi, że faktycznie zostało ono otworzone.

```text
curl http://webapibook-issuetracker.azurewebsites.net/issue/2
```

Oto wynik:

```javascript
{
  "id": "2",
  "title": "Inne zgłoszenie błędu",
  "description": "To jest inne zgłoszenie błędu",
  "status": "Open",
  "links": [
    {
      "rel": "self",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issue/2"
    },
    {
      "rel": "http://webapibook.net/profile#transition",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=transition",
      "action": "transition"
    },
    {
      "rel": "http://webapibook.net/profile#close",
      "href": "http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=close",
      "action": "close"
    }
  ]
}
```

## Weryfikacja
Możesz zobaczyć przeprowadzanie weryfikacji API podczas ponownej próby użycia łącza `open`, co jest nieprawidłowe. Parametr -v wskazuje na wygenerowanie obszerniejszych danych wyjściowych, które pozwalają na poznanie informacji o stanie.

```text
curl -v -d '' http://webapibook-issuetracker.azurewebsites.net/issueprocessor/2?action=open
```

Powinieneś otrzymać poniższą odpowiedź wskazującą na błąd. 

```text
> User-Agent: curl/7.30.0
> Host: webapibook-issuetracker.azurewebsites.net
> Accept: */*
> Content-Length: 0
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 400 Bad Request
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Length: 45
< Content-Type: application/json; charset=utf-8
< Expires: -1
* Server Microsoft-IIS/8.0 is not blacklisted
< Server: Microsoft-IIS/8.0
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Set-Cookie: ARRAffinity=ccfec91eb2c9455382c57d9f048af6af6ab3ef6946377d30ef0a62a0fc14e489;Path=/;Domain=webapibook-issuetracker.azurewebsites.net
< Date: Thu, 16 Oct 2014 06:32:49 GMT
* Błąd HTTP przed zakończeniem wysyłania, zatrzymanie wysyłania
<
{
  "message": "Akcja 'open' jest nieprawidłowa"
* Zamykanie połączenia 0
}
```





