Bizley
9 years ago
3 changed files with 274 additions and 0 deletions
@ -0,0 +1,90 @@
|
||||
Obsługa błędów |
||||
============== |
||||
|
||||
Podczas obsługi żądania RESTfulowego API, w przypadku wystąpienia błędu w zapytaniu użytkownika lub gdy stanie się coś nieprzewidywanego |
||||
z serwerem, możesz po prostu rzucić wyjątkiem, aby powiadomić użytkownika, że coś poszło nieprawidłowo. |
||||
Jeśli możesz zidentyfikować przyczynę błędu (np. żądany zasób nie istnieje), powinieneś rozważyć |
||||
rzucenie wyjątkiem razem z odpowiednim kodem statusu HTTP (np. [[yii\web\NotFoundHttpException]] odpowiada statusowi o kodzie 404). |
||||
Yii wyśle odpowiedź razem z odpowiadającym jej kodem i treścią statusu HTTP. Yii dołączy również do samej odpowiedzi zserializowaną reprezentację |
||||
wyjątku. Przykładowo: |
||||
|
||||
``` |
||||
HTTP/1.1 404 Not Found |
||||
Date: Sun, 02 Mar 2014 05:31:43 GMT |
||||
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y |
||||
Transfer-Encoding: chunked |
||||
Content-Type: application/json; charset=UTF-8 |
||||
|
||||
{ |
||||
"name": "Not Found Exception", |
||||
"message": "The requested resource was not found.", |
||||
"code": 0, |
||||
"status": 404 |
||||
} |
||||
``` |
||||
|
||||
Poniższa lista zawiera kody statusów HTTP, które są używane przez Yii REST framework: |
||||
|
||||
* `200`: OK. Wszystko działa w porządku. |
||||
* `201`: Zasób został poprawnie stworzony w odpowiedzi na żądanie `POST`. Nagłówek `Location` zawiera URL kierujący do nowoutworzonego zasobu. |
||||
* `204`: Żądanie zostało poprawnie przetworzone, ale odpowiedź nie zawiera treści (jak w przypadku żądania `DELETE`). |
||||
* `304`: Zasób nie został zmodyfikowany. Można użyć wersji przetrzymywanej w pamięci podręcznej. |
||||
* `400`: Nieprawidłowe żądanie. Może być spowodowane przez wiele czynników po stronie użytkownika, takich jak przekazanie nieprawidłowych danych JSON, |
||||
nieprawidłowych parametrów akcji, itp. |
||||
* `401`: Nieudana autentykacja. |
||||
* `403`: Autoryzowany użytkownik nie ma uprawnień do danego punktu końcowego API. |
||||
* `404`: Żądany zasób nie istnieje. |
||||
* `405`: Niedozwolona metoda. Sprawdź nagłówek `Allow`, aby poznać dozwolone metody HTTP. |
||||
* `415`: Niewspierany typ mediów. Żądany typ zawartości lub numer wersji jest nieprawidłowy. |
||||
* `422`: Nieudana walidacja danych (dla przykładu w odpowiedzi na żądanie `POST`). Sprawdź treść odpowiedzi, aby poznać szczegóły błędu. |
||||
* `429`: Zbyt wiele żądań. Żądanie zostało odrzucone z powodu osiagnięcia limitu użycia. |
||||
* `500`: Wewnętrzny błąd serwera. To może być spowodowane wewnętrznymi błędami programu. |
||||
|
||||
|
||||
## Modyfikowanie błędnej odpowiedzi <span id="customizing-error-response"></span> |
||||
|
||||
Czasem wymagane może być dostosowanie domyślnego formatu błędnej odpowiedzi. Dla przykładu, zamiast używać różnych statusów HTTP dla oznaczenia różnych błędów, |
||||
można serwować zawsze status 200 i dodawać prawidłowy kod statusu HTTP jako część struktury JSON w odpowiedzi, jak pokazano to poniżej: |
||||
|
||||
``` |
||||
HTTP/1.1 200 OK |
||||
Date: Sun, 02 Mar 2014 05:31:43 GMT |
||||
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y |
||||
Transfer-Encoding: chunked |
||||
Content-Type: application/json; charset=UTF-8 |
||||
|
||||
{ |
||||
"success": false, |
||||
"data": { |
||||
"name": "Not Found Exception", |
||||
"message": "The requested resource was not found.", |
||||
"code": 0, |
||||
"status": 404 |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Aby osiągnąć powyższy efekt, należy skonfigurować odpowiedź na event `beforeSend` dla komponentu `response` w aplikacji: |
||||
|
||||
```php |
||||
return [ |
||||
// ... |
||||
'components' => [ |
||||
'response' => [ |
||||
'class' => 'yii\web\Response', |
||||
'on beforeSend' => function ($event) { |
||||
$response = $event->sender; |
||||
if ($response->data !== null && Yii::$app->request->get('suppress_response_code')) { |
||||
$response->data = [ |
||||
'success' => $response->isSuccessful, |
||||
'data' => $response->data, |
||||
]; |
||||
$response->statusCode = 200; |
||||
} |
||||
}, |
||||
], |
||||
], |
||||
]; |
||||
``` |
||||
|
||||
Powyższy kod zreformatuje odpowiedź (zarówno typu sukces jak i błąd), kiedy `suppress_response_code` zostanie przekazane jako parametr `GET`. |
@ -0,0 +1,110 @@
|
||||
Skrypty wejściowe |
||||
================= |
||||
|
||||
Skrypty wejściowe są pierwszym krokiem procesu bootstrapowania aplikacji. Aplikacja (zarówno web |
||||
jak i konsolowa) posiada pojedynczy skrypt wejściowy. Użytkownicy końcowi wysyłają żądania do skryptów |
||||
wejściowych, które inicjują instancje aplikacji i przekazują do nich te żądania. |
||||
|
||||
Skrypty wejściowe dla aplikacji Web muszą znajdować się w folderach dostępnych dla Web, aby użytkownicy końcowi mogli je wywołać. |
||||
Zwykle nazywane są `index.php`, ale mogą mieć inne nazwy pod warunkiem, że serwery Web potrafią je zlokalizować. |
||||
|
||||
Skrypty wejściowe dla aplikacji konsolowych trzymane są zwykle w [ścieżce głównej](structure-applications.md) |
||||
aplikacji i nazywane `yii` (z sufiksem `.php`). Powinny być wykonywalne, aby użytkownicy |
||||
mogli uruchomić aplikacje konsolowe za pomocą komendy `./yii <ścieżka> [argumenty] [opcje]`. |
||||
|
||||
Skrypty wejściowe wykonują głównie następującą pracę: |
||||
|
||||
* Definiują globalne stałe, |
||||
* Rejestrują [autoloader Composera](https://getcomposer.org/doc/01-basic-usage.md#autoloading), |
||||
* Dołączają plik klasy [[Yii]], |
||||
* Ładują konfigurację aplikacji, |
||||
* Tworzą i konfigurują instancję [aplikacji](structure-applications.md), |
||||
* Wywołują [[yii\base\Application::run()]], aby przetworzyć wysłane żądanie. |
||||
|
||||
|
||||
## Aplikacje Web <span id="web-applications"></span> |
||||
|
||||
Poniżej znajdziesz kod skryptu wejściowego dla [Podstawowego projektu szablonu Web](start-installation.md). |
||||
|
||||
```php |
||||
<?php |
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
defined('YII_ENV') or define('YII_ENV', 'dev'); |
||||
|
||||
// register Composer autoloader |
||||
require(__DIR__ . '/../vendor/autoload.php'); |
||||
|
||||
// include Yii class file |
||||
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); |
||||
|
||||
// load application configuration |
||||
$config = require(__DIR__ . '/../config/web.php'); |
||||
|
||||
// create, configure and run application |
||||
(new yii\web\Application($config))->run(); |
||||
``` |
||||
|
||||
|
||||
## Aplikacje konsoli <span id="console-applications"></span> |
||||
|
||||
Podobnie, poniżej kod skryptu wejściowego dla aplikacji konsolowej: |
||||
|
||||
```php |
||||
#!/usr/bin/env php |
||||
<?php |
||||
/** |
||||
* Yii console bootstrap file. |
||||
* |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
|
||||
// register Composer autoloader |
||||
require(__DIR__ . '/vendor/autoload.php'); |
||||
|
||||
// include Yii class file |
||||
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php'); |
||||
|
||||
// load application configuration |
||||
$config = require(__DIR__ . '/config/console.php'); |
||||
|
||||
$application = new yii\console\Application($config); |
||||
$exitCode = $application->run(); |
||||
exit($exitCode); |
||||
``` |
||||
|
||||
|
||||
## Definiowanie stałych <span id="defining-constants"></span> |
||||
|
||||
Skrypty wejściowe są najlepszym miejscem do definiowania globalnych stałych. Yii wspiera następujące trzy stałe: |
||||
|
||||
* `YII_DEBUG`: określa czy aplikacja działa w trybie debugowania. Podczas tego trybu aplikacja |
||||
przetrzymuje więcej informacji w logach i zdradza szczegóły stosu błędów, kiedy rzucony jest wyjątek. Z tego powodu |
||||
tryb debugowania powinien być używany głównie podczas fazy deweloperskiej. Domyślną wartością `YII_DEBUG` jest false. |
||||
* `YII_ENV`: określa środowisko, w którym aplikacja działa. Opisane jest to bardziej szczegółowo |
||||
w sekcji [Konfiguracje](concept-configurations.md#environment-constants). |
||||
Domyślną wartością `YII_ENV` jest `'prod'`, co oznacza, że aplikacja jest uruchomiona w środowisku produkcyjnym. |
||||
* `YII_ENABLE_ERROR_HANDLER`: określa czy uruchomić obsługę błędów przygotowaną przez Yii. Domyślną wartością tej stałej jest true. |
||||
|
||||
Podczas definiowania stałej często korzystamy z poniższego kodu: |
||||
|
||||
```php |
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
``` |
||||
|
||||
co odpowiada: |
||||
|
||||
```php |
||||
if (!defined('YII_DEBUG')) { |
||||
define('YII_DEBUG', true); |
||||
} |
||||
``` |
||||
|
||||
Jak widać pierwszy sposób jest bardziej zwięzły i łatwiejszy do zrozumienia. |
||||
|
||||
Definiowanie stałych powinno odbyć się na samym początku skryptu wejściowego, aby odniosło skutek podczas dołączania pozostałych |
||||
plików PHP. |
@ -0,0 +1,74 @@
|
||||
Testowanie |
||||
========== |
||||
|
||||
Testowanie jest istotnym elementem produkcji każdego oprogramowania. Niezależnie, czy jesteśmy tego świadomi, czy też nie, testy przeprowadzamy nieustannie. |
||||
Dla przykładu, kiedy napiszemy klasę w PHP, możemy debugować ją krok po kroku lub po prostu użyć wyrażeń jak echo lub die, aby sprawdzić, czy implementacja |
||||
działa zgodnie z naszym początkowym planem. W przypadku aplikacji web wprowadzamy testowe dane w formularzach, aby upewnić się, że strona odpowiada tak, jak powinna. |
||||
|
||||
Proces testowania może zostać zautomatyzowany, dzięki czemu za każdym razem, kiedy musimy coś sprawdzić, wystarczy wywołać kod, który zrobi to za nas. |
||||
Kod, który weryfikuje zgodność wyniku z planowaną odpowiedzią, jest nazywany testem, a proces jego tworzenia i późniejszego wykonania jest nazywany testowaniem zautomatyzowanym, |
||||
co jest głównym tematem tych rozdziałów. |
||||
|
||||
|
||||
Tworzenie kodu z testami |
||||
------------------------ |
||||
|
||||
Tworzenie kodu opartego na testach (Test-Driven Development, TDD) i opartego na zachowaniach (Behavior-Driven Development, BDD) jest podejściem deweloperskim |
||||
opierającym się na opisywaniu zachowania fragmentu kodu lub też całej jego funkcjonalności jako zestawu scenariuszy lub testów przed napisaniem właściwego kodu |
||||
i dopiero potem stworzeniu implementacji, która pozwoli na poprawne przejście testów, spełniających zadane kryteria. |
||||
|
||||
Proces tworzenia funkcjonalności wygląda następująco: |
||||
|
||||
- Stwórz nowy test, opisujący funkcjonalność do zaimplementowania. |
||||
- Uruchom nowy test i upewnij się, że zakończy się błędem. To właściwe zachowanie, ponieważ nie ma jeszcze implementacji funkcjonalności. |
||||
- Napisz prosty kod, który przejdzie poprawnie nowy test. |
||||
- Uruchom wszystkie testy i upewnij się, że wszystkie zakończą się poprawnie. |
||||
- Ulepsz kod, sprawdzając czy testy wciąż są zdane. |
||||
|
||||
Po zakończeniu proces jest powtarzany dla kolejnej funkcjonalności lub ulepszenia. Jeśli istniejąca funkcjonalność ma być zmodyfikowana, |
||||
testy powinny być również zmienione. |
||||
|
||||
> **Wskazówka**: Jeśli czujesz, że tracisz czas, przeprowadzając dużo krótkich i prostych iteracji, spróbuj objąć testowym scenariuszem więcej działań, |
||||
> aby sprawdzić więcej kodu, przed ponownym uruchomieniem testów. Jeśli debugujesz zbyt dużo, spróbuj zrobić dokładnie na odwrót. |
||||
|
||||
Powodem tworzenia testów przed jakąkolwiek implementacją, jest możliwość skupienia się na tym, co chcemy osiągnąć, zanim przystąpimy do "w jaki sposób to zrobić". |
||||
Zwykle prowadzi to do stworzenia lepszej warstwy abstrakcji i łatwiejszej obsługi testów w przypadku poprawek funkcjonalności. |
||||
|
||||
Podsumowując, zalety takiego projektowania są następujące: |
||||
|
||||
- Pozwala na skupienie się na pojedynczej rzeczy na raz, dzięki czemu pozwala na lepsze planowanie i implementacje. |
||||
- Obejmuje testami więcej funkcjonalności w większym stopniu, co oznacza, że jeśli testy zakończyły się poprawnie jest spore prawdopodobieństwo, że wszystko działa poprawnie. |
||||
|
||||
Na dłuższą metę przynosi to zwykle efekt w postaci mnóstwa oszczędzonego czasu i problemów. |
||||
|
||||
> **Wskazówka**: Jeśli chcesz dowiedzieć się więcej na temat reguł ustalania wymagań dla oprogramowania i modelowania istoty tego rozdziału, |
||||
> warto zapoznać się z domenowym podejściem do tworzenia aplikacji [(Domain Driven Development, DDD)](https://pl.wikipedia.org/wiki/Domain-Driven_Design). |
||||
|
||||
Kiedy i jak testować |
||||
-------------------- |
||||
|
||||
Podejście typu "testy najpierw" opisane powyżej, ma sens w przypadku długofalowych i relatywnie skomplikowanych projektów i może być przesadne w przypadku prostszych. |
||||
Przesłanki, kiedy testy są odpowiednie są następujące: |
||||
|
||||
- Projekt jest już duży i skomplikowany. |
||||
- Wymagania projektowe zaczynają być skomplikowane. Projekt wciąż się powiększa. |
||||
- Projekt jest planowany jako długoterminowy. |
||||
- Koszty potencjalnych błędów są zbyt duże. |
||||
|
||||
Nie ma nic złego w tworzeniu testów obejmujących zachowania istniejących implementacji. |
||||
|
||||
- Projekt jest oparty starszym kodzie i stopniowo przepisywany. |
||||
- Projekt, nad którym masz pracować, nie ma w ogóle testów. |
||||
|
||||
W niektórych przypadkach jakakolwiek forma automatycznego testu może być nadmiarowa: |
||||
|
||||
- Projekt jest prosty i nie jest rozbudowywany. |
||||
- Projekt jest jednorazowym zadaniem, które nie będzie rozwijane. |
||||
|
||||
Pomimo tego, jeśli masz na to czas, automatyzacja testowania jest również dobrym pomysłem. |
||||
|
||||
|
||||
Biblioteka |
||||
------------- |
||||
|
||||
- Test Driven Development: By Example - Kent Beck. (ISBN: 0321146530) |
Loading…
Reference in new issue