angular restmod
TRANSCRIPT
Angular Restmodwygodny sposób na komunikację z API
Marcin GajdaFront-End developerThe Software house
Angular Restmod?
● implementuje Active Record● mapuje dane z REST API na modele● pozwala korzystać z kolekcji modeli● automatyzuje tworzenie relacji
REST API – bezstanowy interfejs programistyczny
oparty o model klient - serwer i protokół HTTP.
Relacje?
● zależności między obiektami● obsługa “1 do 1” oraz “1 do n”● wsparcie dla modeli “inline”● automatyczne rzutowanie na typ● generowanie adresów API
Konfiguracja Restmoda● system wstawek● wstawka może składać się z:
○ ogólnej konfiguracji ($config)○ uchwytów zdarzeń ($hooks)○ rozszerzeń ($extend)○ ustawień dla atrybutów
● podział na:○ konfiguracja globalna○ konfiguracja “per definicja”
Ogólne ustawienia ($config)
Pozwala na ustawienie m.in:● nazwy klucza głównego● źródła metadanych● głównego adresu API
wow such configurable
Hooki ($hooks)
● niczym Angular interceptors● pozwalają:
○ modyfikować żądanie przed wysłaniem○ zmieniać w locie odpowiedź○ sterować parsowaniem odpowiedzi○ globalnie reagować na błędy API
Duża ilość do wyboru● before-create● after-create● after-create-error● before-save● after-save● after-save-error● before-update● after-update● after-update-error● before-destroy● after-destroy● after-destroy-error
● before-request● after-request● after-request-error● before-fetch● before-fetch-many● after-feed● after-feed-error● after-fetch-many● after-fetch-many-error● after-init● after-remove● before-render
Rozszerzenia ($extend)
● nadpisywanie metod Restmoda● dodawanie nowych metod
○ do statycznego interfejsu○ dla modeli○ dla kolekcji
Sterowanie atrybutami
● wartości domyślne● maskowanie atrybutów● ustawienia (de)serializacji● konfiguracja relacji
Może przykład?
Przykładowy scenariusz
● API udostępnia: ○ informacje o muzykach ○ informacje o płytach
● Dodatkowo można:○ osobno pobrać historię zespołu○ szukać artystów po nazwach
● API wymaga tokenu
Globalna konfiguracja
module.config(['restmodProvider',
function (restmodProvider) {
restmodProvider.rebase("MyAPIStyle");
restmodProvider.rebase({ ... })
}
]);
Api Style - globalna konfiguracja która dostosowuje modele do stylu API
Piszemy API Style:
module.factory('MyAPIStyle', function (restmod) {
return restmod.mixin('DefaultPacker', {
$config: {
primaryKey: "id",
jsonMeta: "meta"
},
$extend: {...}, $hooks: {...}, ...
});
})
Ustawiamy token autoryzacyjnymodule.config(['restmodProvider',
function (restmodProvider) {
restmodProvider.rebase({ $hooks: { 'before-request': function (request) { request.headers["X-Token"] = TOKEN; return request; } }
});
});
})
Rzut oka na /artists{ artist: { id: 1, name: "Django Reinhardt", image: "/img/reinhardt.png", tags: [ {value: "guitar"}, {value: "jazz"} ]
},meta: {...}
}/img/reinhardt.png
GET: /artists/1
Tworzymy definicję modelu Artist
module.factory(‘ArtistModel’, function (restmod) {
restmod.model('/artists') .mix({ $hooks: {...}, $extend: {...}, $config: {name: 'artist'}, // ... });
});
Podstawy korzystania z modelu
var django = ModelArtist.$find(1);// GET: /artists/1
django.$then(function(model){ console.log( model.image ); // > "/img/reinhardt.png"});
Tworzymy nowy wpis w API...
var newBand = ModelArtist.$create({name: "Flogging Molly"
});// POST: /artists
… i potem go edytujemy
newBand.image = "/img/shamrock.jpg";
newBand.$save(); // PUTnewBand.$save(["image"]); // PATCH
… lub tylko jej fragment
bands = ModelArtist.$search({name: "Stevie"
}).$refresh();
// GET: /artists?name=Stevie
Dodajemy metodę do modelu...module.factory("ArtistModel", function (restmod) { restmod.model('/artists').mix({ $extend: { Record: { getImagePath: function(){ return API_PATH + this.image; } } }, $config: {...}, $hooks: {...}, ... });});
… i korzystamy z niej
var image = newBand.getImagePath();
// https://localhost/api/img/shamrock.jpg
Oprócz interfejsu Record można także rozszerzać intrfejsy List, Scope, Static i inne.
Konfigurujemy atrybuty
module.factory(‘ArtistModel’, function (restmod) { restmod.model('/artists').mix({
image: { init: "/img/default.png" }, albums: { hasMany: "AlbumModel" }, history: { hasOne: "HistoryModel" }, tags: { hasMany: "TagModel" }, $hooks: {...}, $extend: {...}, $config: {...} });});
Wykorzystujemy relacje
var albums = django.albums.$fetch();// GET: /artists/1/albums
var history = django.history.$fetch();// GET: /artists/1/history
var tags = django.tags;
Zakładając, że zdefiniowaliśmy TagModel, HistoryModel, AlbumModel:
Podsumowanie - wady● niedopowiedzenia i błędy w dokumentacji● modele są zawsze związane z kolekcją● brak wbudowanych metod hurtowych● tylko jedno wbudowane API style
Podsumowanie - zalety● sporo możliwości konfiguracyjnych● wpływ na przebieg działania modułu● możliwość używania z każdym REST API● dobrze współpracuje z formularzami● wsparcie dla relacji