Wprowadzenie do WP-API

Post on 15-Apr-2017

4.049 views 4 download

Transcript of Wprowadzenie do WP-API

Wprowadzenie do WP-APITomasz Dziuda

Tomasz Dziuda

Lead Developer @

@dziudek

http://dziudek.pl

http://dziudek.github.io/wp-links

http://dziudek.github.io/dev-links

Disclaimer

Będę mówił o WP-API w wersji v.2.* obecnie w wersji beta, ale to najbliższa przyszłość WP-API

Idea

Źródło: https://wordpress.org/plugins/rest-api/

+WP-API

+WP-API

GET/POST/PUT/DELETEOpcjonalnie: {“json”: “data”}

GET/POST/PUT/DELETE

{“json”: “data”}

+WP-API

Opcjonalnie: {“json”: “data”}

{“json”: “data”}

wp_ajax_{action} wp_ajax_nopriv_{action}

+WP-API

GET/POST/PUT/DELETEOpcjonalnie: {“json”: “data”}

{“json”: “data”}

wp_ajax_{action} wp_ajax_nopriv_{action}

+WP-API

GET/POST/PUT/DELETEOpcjonalnie: {“json”: “data”}

JSON jako nośnik danych

Wtyczka JSON Viewer: https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh/

Struktura URLi

wp-json/

Struktura URLi

wp-json/<namespace>

wp/v2

Struktura URLi

wp-json/<namespace>/<zasób>

wp/v2 posts

Struktura URLi

wp-json/<namespace>/<zasób>/<id_lub_filtr>

wp/v2 posts 128

Struktura URLi

wp-json/<namespace>/<zasób>/<id_lub_filtr>/<dodatkowe_zasoby>

wp/v2 posts 128 terms/tag

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

GET wp-json/wp/v2/posts/ " !

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

GET wp-json/wp/v2/posts/

GET wp-json/wp/v2/posts/128

" !

" !

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

GET wp-json/wp/v2/posts/

GET wp-json/wp/v2/posts/128

POST wp-json/wp/v2/posts/

" !

{ }

" !

!

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

GET wp-json/wp/v2/posts/

GET wp-json/wp/v2/posts/128

POST wp-json/wp/v2/posts/

PUT wp-json/wp/v2/posts/128

" !

{ }

" !

!

{ } !

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

GET wp-json/wp/v2/posts/

GET wp-json/wp/v2/posts/128

POST wp-json/wp/v2/posts/

PUT wp-json/wp/v2/posts/128

DELETE wp-json/wp/v2/posts/128

" !

{ }

" !

!

{ } !

!

! " { }Wymaga autoryzacji Nie wymaga autoryzacji Wymaga przesłania danych JSON

Przykłady

Przykłady

wp-json/wp/v2/posts/303

wp-json/wp/v2/posts?filter[cat]=1,2,3

wp-json/wp/v2/posts?filter[posts_per_page]=20

wp-json/terms/category

wp-json/users/me

Przykłady

wp-json/wp/v2/posts/303

wp-json/wp/v2/posts?filter[cat]=1,2,3

wp-json/wp/v2/posts?filter[posts_per_page]=20

wp-json/terms/category

wp-json/users/me

Przykłady

wp-json/wp/v2/posts/303

wp-json/wp/v2/posts?filter[cat]=1,2,3

wp-json/wp/v2/posts?filter[posts_per_page]=20

wp-json/terms/category

wp-json/users/me

Przykłady

wp-json/wp/v2/posts/303

wp-json/wp/v2/posts?filter[cat]=1,2,3

wp-json/wp/v2/posts?filter[posts_per_page]=20

wp-json/wp/v2/terms/category

wp-json/wp/v2/users/me

Przykłady

wp-json/wp/v2/posts/303

wp-json/wp/v2/posts?filter[cat]=1,2,3

wp-json/wp/v2/posts?filter[posts_per_page]=20

wp-json/wp/v2/terms/category

wp-json/wp/v2/users/me

Sposoby autoryzacji

Cookie Auth

• Standardowa metoda autoryzacji dla wtyczek i motywów

• Wymaga przesłania w zapytaniu AJAX-owym dodatkowego nagłówka X-WP-Nonce http://wp-api.org/guides/authentication.html#cookie-authentication

Cookie Auth

• Standardowa metoda autoryzacji dla wtyczek i motywów

• Wymaga przesłania w zapytaniu AJAX-owym dodatkowego nagłówka X-WP-Nonce http://v2.wp-api.org/guide/authentication/

OAuth

• Dla aplikacji zewnętrznych - webowych, mobilnych, desktopowych

• Wymaga dodatkowego pluginu - OAuth Serverhttps://github.com/WP-API/OAuth1

• Wsparcie tylko dla OAuth 1.*

• Niestety obecnie nie ma UI do zarządzania kluczami

OAuth

• Dla aplikacji zewnętrznych - webowych, mobilnych, desktopowych

• Wymaga dodatkowego pluginu - OAuth Serverhttps://github.com/WP-API/OAuth1

• Wsparcie tylko dla OAuth 1.*

• Niestety obecnie nie ma UI do zarządzania kluczami

OAuth

• Dla aplikacji zewnętrznych - webowych, mobilnych, desktopowych

• Wymaga dodatkowego pluginu - OAuth Serverhttps://github.com/WP-API/OAuth1

• Wsparcie tylko dla OAuth 1.*

• Niestety obecnie nie ma UI do zarządzania kluczami

OAuth

• Dla aplikacji zewnętrznych - webowych, mobilnych, desktopowych

• Wymaga dodatkowego pluginu - OAuth Serverhttps://github.com/WP-API/OAuth1

• Wsparcie tylko dla OAuth 1.*

• Niestety obecnie nie ma UI do zarządzania kluczami

Basic Auth

• Tylko do środowisk testowych, istnieje duże ryzyko wycieku hasła wskutek braku szyfrowania

• Wymaga dodatkowej wtyczki: Basic Auth https://github.com/WP-API/Basic-Auth

Basic Auth

• Tylko do środowisk testowych, istnieje duże ryzyko wycieku hasła wskutek braku szyfrowania

• Wymaga dodatkowej wtyczki: Basic Auth https://github.com/WP-API/Basic-Auth

Istotne zmiany pomiędzy REST API v.1.* i v.2.*

Przestrzenie nazw

Przestrzenie nazw

Nasz motyw lub wtyczka może korzystać z własnej przestrzeni nazw w REST API.

Tworzenie nowych endpointów API poprzez register_rest_route wymaga zdefiniowania przestrzeni nazw.

Domyślna przestrzeń nazw to wp/v2

Przestrzenie nazw

Nasz motyw lub wtyczka może korzystać z własnej przestrzeni nazw w REST API.

Tworzenie nowych endpointów API poprzez register_rest_route wymaga zdefiniowania przestrzeni nazw.

Domyślna przestrzeń nazw to wp/v2

Przestrzenie nazw

Nasz motyw lub wtyczka może korzystać z własnej przestrzeni nazw w REST API.

Tworzenie nowych endpointów API poprzez register_rest_route wymaga zdefiniowania przestrzeni nazw.

Domyślna przestrzeń nazw to wp/v2

Implementacja HAL

Źródło: http://stateless.co/hal_specification.html

Implementacja HALHAL - Hypertext Application Language

Źródło: http://stateless.co/hal_specification.html

Implementacja HALHAL - Hypertext Application Language

Wprowadza dla zasobów kolekcje _links i _embedded

Źródło: http://stateless.co/hal_specification.html

Implementacja HALHAL - Hypertext Application Language

Wprowadza dla zasobów kolekcje _links i _embedded

_links zawiera adresy powiązanych zasobów

_embedded zawiera dane powiązanych zasobów gdy dodamy w URLu &_embed

Źródło: http://stateless.co/hal_specification.html

Nowe endpointywp/v2/comments

wp/v2/pages

wp/v2/terms

wp/v2/types

wp/v2/statuses

Możliwości

Motywy jako SPA

Łatwa komunikacja z aplikacjami

Migrowanie danych

Migrowanie danych

Migrowanie danych

JSON XML SQL

YAML RSS Atom

Migrowanie danych

JSON

JSON XML SQL

YAML RSS Atom

Przetwarzanie danych

Przetwarzanie danych

JSON

Przetwarzanie danych

JSON

Przetwarzanie danych

Własne endpointyhttp://v2.wp-api.org/extending/adding/

Filtry i akcje

• Akcja rest_insert_post - pozwala zmodyfikować dane przed dodaniem do bazy

• Filtr rest_prepare_{POST_TYPE} - może w niektórych wypadkach zastąpić własne endpointy

• Akcja rest_api_init - pozwala dodawać pola i nowe endpointy oraz np. ograniczyć zapytania do określonej puli IP lub zarejestrowanych kluczy

• Akcja rest_insert_post - pozwala zmodyfikować dane przed dodaniem do bazy

• Filtr rest_prepare_{POST_TYPE} - może w niektórych wypadkach zastąpić własne endpointy

• Akcja rest_api_init - pozwala dodawać pola i nowe endpointy oraz np. ograniczyć zapytania do określonej puli IP lub zarejestrowanych kluczy

• Akcja rest_insert_post - pozwala zmodyfikować dane przed dodaniem do bazy

• Filtr rest_prepare_{POST_TYPE} - może w niektórych wypadkach zastąpić własne endpointy

• Akcja rest_api_init - pozwala dodawać pola i nowe endpointy oraz np. ograniczyć zapytania do określonej puli IP lub zarejestrowanych kluczy

Kilka ciekawostek

Zmiana URLa REST API

Możemy zmienić URL do API (domyślnie wp-json) poprzez filtr:

rest_url_prefix

Podstawowe informacje o stronie

Pod adresem wp-json/ znajdują się podstawowe dane witryny:

• nazwa, • opis, • dostępne przestrzenie nazw, • lista endpointów

Własne metody autoryzacji

• Wymagają implementacji z użyciem filtra rest_authentication_errors

• Można zaimplementować np. JSON Web Tokenshttp://jwt.io/

Własne metody autoryzacji

• Wymagają implementacji z użyciem filtra rest_authentication_errors

• Można zaimplementować np. JSON Web Tokenshttp://jwt.io/

Zmiana klasy obsługującej API

Korzystając z filtra wp_rest_server_class możemy podmienić klasę WP_REST_Server na własną klasę

REST API a mobilna agenda

WordCampa

+

+Raw JSON data

+Raw JSON data

+Raw JSON data speakers.json

presentations.json

+Raw JSON data speakers.json

presentations.json

JSON~320kB

JSON~60kB

Motyw jako SPA

Motyw-mapa

Co wykorzystać?

REST API

Adresy URL, które wykorzystamy:

• wp-json/wp/v2/terms/category/

• wp-json/wp/v2/posts?filter[posts_per_page]=200

• wp-json/wp/v2posts?filter[posts_per_page]=200&filter[cat]=1,2,3

REST API

Adresy URL, które wykorzystamy:

• wp-json/wp/v2/terms/category/

• wp-json/wp/v2/posts?filter[posts_per_page]=200

• wp-json/wp/v2posts?filter[posts_per_page]=200&filter[cat]=1,2,3

REST API

Adresy URL, które wykorzystamy:

• wp-json/wp/v2/terms/category/

• wp-json/wp/v2/posts?filter[posts_per_page]=200

• wp-json/wp/v2posts?filter[posts_per_page]=200&filter[cat]=1,2,3

REST API

Adresy URL, które wykorzystamy:

• wp-json/wp/v2/terms/category/

• wp-json/wp/v2/posts?filter[posts_per_page]=200

• wp-json/wp/v2posts?filter[posts_per_page]=200&filter[cat]=1,2,3

Handlebarshttp://handlebarsjs.com/

<script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3>

<ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>

Handlebarshttp://handlebarsjs.com/

<script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3>

<ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>

Handlebarshttp://handlebarsjs.com/

<script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3>

<ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>

Inne

Inne• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial

• LocalStorage - do przechowywania filtrów

• History API - aby mieć dostęp poprzez URL do konkretnych miejsc

• Snazzy mapshttps://snazzymaps.com/

• Travel icon sethttp://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/

Inne• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial

• LocalStorage - do przechowywania filtrów

• History API - aby mieć dostęp poprzez URL do konkretnych miejsc

• Snazzy mapshttps://snazzymaps.com/

• Travel icon sethttp://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/

Inne• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial

• LocalStorage - do przechowywania filtrów

• History API - aby mieć dostęp poprzez URL do konkretnych miejsc

• Snazzy mapshttps://snazzymaps.com/

• Travel icon sethttp://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/

Inne• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial

• LocalStorage - do przechowywania filtrów

• History API - aby mieć dostęp poprzez URL do konkretnych miejsc

• Snazzy mapshttps://snazzymaps.com/

• Travel icon sethttp://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/

Inne• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial

• LocalStorage - do przechowywania filtrów

• History API - aby mieć dostęp poprzez URL do konkretnych miejsc

• Snazzy mapshttps://snazzymaps.com/

• Travel icon sethttp://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/

Problemy?

Wprowadzanie pozycji elementów na mapie

Wprowadzanie pozycji elementów na mapie

Wtyczka Pronamic Google Maps https://wordpress.org/plugins/pronamic-google-maps/

Wprowadzanie pozycji elementów na mapie

Advanced Custom Fields https://wordpress.org/plugins/advanced-custom-fields/

Duża liczba markerów

Duża liczba markerów

• Marker Clusterer https://googlemaps.github.io/js-marker-clusterer/docs/examples.html

• Gorsze przypadki omówimy później ;)

Wpis

Dane geolokalizacyjne

Kategoria

Kategoria

Tagi

Adres

Najważniejsze pliki motywu

• index.php - jedyny plik wyświetlający szablon

• index-templates.php - przechowuje szablony Handlebars

• functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS

Najważniejsze pliki motywu

• index.php - jedyny plik wyświetlający szablon

• index-templates.php - przechowuje szablony Handlebars

• functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS

Najważniejsze pliki motywu

• index.php - jedyny plik wyświetlający szablon

• index-templates.php - przechowuje szablony Handlebars

• functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS

Najważniejsze pliki motywu

• index.php - jedyny plik wyświetlający szablon

• index-templates.php - przechowuje szablony Handlebars

• functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS

• tgm.php - do ułatwienia/wymuszenia instalacji potrzebnych wtyczek

Wczytywanie konfiguracji wstępnej z ekranu personalizacji motywu

wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’));

$app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'),);

wp_localize_script( 'tm-app', 'appConfig', $app_config );

Wczytywanie konfiguracji wstępnej z ekranu personalizacji motywu

wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’));

$app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'),);

wp_localize_script( 'tm-app', 'appConfig', $app_config );

Wczytywanie konfiguracji wstępnej z ekranu personalizacji motywu

wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’));

$app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'),);

wp_localize_script( 'tm-app', 'appConfig', $app_config );

Pobieranie danych$.ajax({

url: apiUrl + “posts?filter[posts_per_page]=200"}).done(function( data ) {// przetwarzanie danych

});

Pobieranie danych$.ajax({

url: apiUrl + “posts?filter[posts_per_page]=200"}).done(function( data ) {// przetwarzanie danych

});

Pobieranie danych$.ajax({

url: apiUrl + “posts?filter[posts_per_page]=200"}).done(function( data ) { // przetwarzanie danych});

Pobieranie danych$.ajax({ method: ‘GET’,

url: apiUrl + “posts?filter[posts_per_page]=200"}).done(function( data ) { // przetwarzanie danych});

Pobieranie danych$.ajax({ method: ‘GET’,

cache: false, url: apiUrl + “posts?filter[posts_per_page]=200"}).done(function( data ) { // przetwarzanie danych});

Usuwanie/modyfikowanie pól z odpowiedzi REST API jest NIEBEZPIECZNE

Lepiej stworzyć własne zoptymalizowane endpointy w przestrzeni nazw motywu lub dodać brakujące pola

W wypadku dodawana własnych pól, warto dodać im prefiksy celem uniknięcia konfliktów z innymi wtyczkami

i motywami modyfikującymi odpowiedzi API

np. tm_geodata

Dodawanie danych do wpisufunction PREFIX_register_FIELD_NAME() { register_api_field('TYPE', ‘PREFIX_FIELD_NAME', array( 'get_callback' => 'PREFIX_get_FIELD_NAME', 'update_callback' => null, 'schema' => null ) );

}

add_action('rest_api_init', ‘PREFIX_register_FIELD_NAME');

Dodawanie danych do wpisufunction PREFIX_register_FIELD_NAME() { register_api_field('TYPE', ‘PREFIX_FIELD_NAME', array( 'get_callback' => 'PREFIX_get_FIELD_NAME', 'update_callback' => null, 'schema' => null ) );

}

add_action('rest_api_init', ‘PREFIX_register_FIELD_NAME');

Dodawanie danych do wpisufunction PREFIX_register_FIELD_NAME() { register_api_field('TYPE', ‘PREFIX_FIELD_NAME', array( 'get_callback' => 'PREFIX_get_FIELD_NAME', 'update_callback' => null, 'schema' => null ) );

}

add_action('rest_api_init', ‘PREFIX_register_FIELD_NAME');

Dodawanie danych do wpisufunction PREFIX_register_FIELD_NAME() { register_api_field('TYPE', ‘PREFIX_FIELD_NAME', array( 'get_callback' => 'PREFIX_get_FIELD_NAME', 'update_callback' => null, 'schema' => null ) );

}

add_action('rest_api_init', ‘PREFIX_register_FIELD_NAME');

Dodawanie danych do wpisufunction tm_register_category() { register_api_field( 'post', 'tm_category', array( 'get_callback' => 'tm_get_category', 'update_callback' => null, 'schema' => null ) );

}

add_action( 'rest_api_init', 'tm_register_category');

function tm_get_category( $object, $field_name, $request ) {$category_slug = null;$categories = get_the_category($object['id']);

if(count($categories)) {$category_slug = $categories[0]->slug;

}

return $category_slug;}

Dodawanie danych do wpisu

Co dalej?

1 wpis = 2-5kB 100 wpisów = ~200-500kB

1 wpis = 2-5kB 100 wpisów = ~200-500kB

Dla większej liczby markerów

• Utworzenie własnych end-pointów do serwowania danych markerów:

• ID,

• Dane geolokalizacyjne

• Kategoria

• Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/posts/<id>

Dla większej liczby markerów

• Utworzenie własnych end-pointów do serwowania danych markerów:

• ID,

• Dane geolokalizacyjne

• Kategoria

• Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/posts/<id>

Dla większej liczby markerów

• Utworzenie własnych end-pointów do serwowania danych markerów:

• ID,

• Dane geolokalizacyjne

• Kategoria

• Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/wp/v2/posts/<id>

Gdy mamy bardzo dużo markerów

• Wczytywanie markerów zależnie od widocznego obszaru mapy

• Przygotowanie end-pointu, który na bazie zakresu szerokości i długości geograficznej zwróci listę markerów na danym obszarze

Gdy mamy bardzo dużo markerów

• Wczytywanie markerów zależnie od widocznego obszaru mapy

• Przygotowanie endpointu, który na bazie zakresu szerokości i długości geograficznej zwróci listę markerów na danym obszarze

Kod przykładu:

https://github.com/dziudek/theme-map

Podsumowanie

Podsumowanie

• REST API tworzy zupełnie nowe obszary wykorzystania wtyczek i motywów

• REST API jest bardzo skalowalne i edytowalne

• Trzeba pamiętać, że nie tylko my będziemy korzystać z REST API na danej instalacji WP

Podsumowanie

• REST API tworzy zupełnie nowe obszary wykorzystania wtyczek i motywów

• REST API jest bardzo skalowalne i edytowalne

• Trzeba pamiętać, że nie tylko my będziemy korzystać z REST API na danej instalacji WP

Podsumowanie

• REST API tworzy zupełnie nowe obszary wykorzystania wtyczek i motywów

• REST API jest bardzo skalowalne i edytowalne

• Trzeba pamiętać, że nie tylko my będziemy korzystać z REST API na danej instalacji WP

Pytania?