3. Agenda
• REST – co to jest?
• REST – jak korzystać efektywnie
• Komunikacja HTTP na Androidzie
• Biblioteki usprawniające pisanie aplikacji
• Komunikacja HTTP i bazy danych
5. REST – co to jest?
REpresentational State Transfer (REST) is a style of
software architecture for distributed systems such as
the World Wide Web
Roy Fielding
6. REST – co to jest?
Cechy serwisu RESTful
• architektura klient-serwer
• bezstanowość
• cache odpowiedzi
• system warstwowy
• uniwersalny interfejs
7. REST – co to jest?
Struktura URI
• Kolekcje
• Zasoby
• Kontrolery
https://api.rwozniak.com/users
https://api.rwozniak.com/users/20
https://api.rwozniak.com/export
8. REST – co to jest?
Operacje CRUD
POST = Create
GET = Read
PUT = Update
DELETE = Delete
9. REST – co to jest?
Create
$ curl -v -X POST -d "..." https://api.rwozniak.com/users
> POST /users HTTP/1.1
>
< HTTP/1.1 201 Created
< Location /users/113
< Content-Length: 61
< Content-Type: application/json
<
[{"id":113,"firstname":"Joanna","lastname":"Kowalska","age":31}]
10. REST – co to jest?
Read
$ curl -v https://api.rwozniak.com/users/113
> GET /users/113 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Length: 61
< Content-Type: application/json
<
{"id":113,"firstname":"Joanna","lastname":"Kowalska","age":31}
11. REST – co to jest?
Update
$ curl -v -X PUT -d "..." https://api.rwozniak.com/users/113
> PUT /users/113 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Length: 61
< Content-Type: application/json
<
{"id":113,"firstname":"Joanna","lastname":"Kowalska","age":18}
12. REST – co to jest?
Delete
$ curl -v -X DELETE https://api.rwozniak.com/users/113
> DELETE /users/113 HTTP/1.1
>
< HTTP/1.1 204 No Content
< Content-Length: 0
< Content-Type: application/json
<
13. REST – więcej
REST - więcej
• kody HTTP odpowiedzi
• wykorzystanie nagłówków
16. REST – więcej
Programista też człowiek
imgsrc: http://thefuturebuzz.com/wp-content/uploads/2011/10/data.jpg
17. REST – więcej
Programmer-friendly
{
"http_code": 400,
"error": "validation_errors",
"error_title": "Set Creation Error",
"error_description": "The following validation errors occurred:nYou must have a
titlenBoth the terms and definitions are mandatory",
"validation_errors": [
"You must have a title",
"Both the terms and definitions are mandatory",
"You must specify the terms language",
"You must specify the definitions language"
]
}
src: https://quizlet.com/api/2.0/docs/api_intro/
19. Android i HTTP
Android i komunikacja HTTP
• Apache HTTP Client
– DefaultHttpClient, AndroidHttpClient
– stabilny, mało błędów
– brak aktywnego dewelopmentu ze strony teamu Androida
• HttpURLConnection
– na początku trochę błędów, ale sukcesywnie rozwijany
– przeźroczysta kompresja odpowiedzi (gzip)
– cache odpowiedzi
– aktywny dewelopment
20. Android i HTTP
HttpClient
public DefaultHttpClient createHttpClient() {
final SchemeRegistry supportedSchemes = new SchemeRegistry();
supportedSchemes.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
supportedSchemes.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
final HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, TIMEOUT * 1000);
HttpConnectionParams.setSoTimeout(params, TIMEOUT * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
HttpClientParams.setRedirecting(httpParams, false);
final ClientConnectionManager ccm = new ThreadSafeClientConnManager(httpParams, supportedSchemes);
return new DefaultHttpClient(ccm, httpParams);
}
22. Android i HTTP
JSON parser
{"id":131,"firstname":"Joanna","lastname":"Kowalska","age":18}
public class User {
public long id;
public String firstname;
public String lastname;
public int age;
}
23. Android i HTTP
JSON parser
public User parse( String response ) throws JSONException {
User user = new User();
JSONObject json = new JSONObject( response );
user.id = json.getLong( "id" );
user.firstname = json.getString( "firstname" );
user.lastname = json.getString( "lastname" );
user.age = json.getInt( "age" );
return user;
}
25. Pomocne biblioteki - Gson
Gson
• biblioteka od Google
• konwersja obiektów Java do reprezentacji JSON
• i oczywiście w drugą stronę
• annotacje
• wsparcie dla złożonych obiektów
src: https://sites.google.com/site/gson/
26. Pomocne biblioteki - Gson
Porównanie
public User parse( String response ) throws JSONException {
User user = new User();
JSONObject json = new JSONObject( response );
user.id = json.getLong( "id" );
user.firstname = json.getString( "firstname" );
user.lastname = json.getString( "lastname" );
user.age = json.getInt( "age" );
return user;
}
public User parse( String response ) {
Gson gson = new Gson();
return gson.fromJson( response, User.class );
}
public User parse( String response ) {
return new Gson().fromJson( response, User.class );
}
27. Pomocne biblioteki - Gson
Bardziej złożona klasa
public class User {
public String username;
@SerializedName("account_type") public AccountType accountType;
@SerializedName("sign_up_date") public long signupDate;
@SerializedName("profile_image") public String profileImage;
public List<Group> groups;
@Since(1.1) public String newField;
}
28. Pomocne biblioteki - CRest
CRest
• po prostu Client REST
• ułatwia komunikację z serwisami typu RESTful
• annotacje
• duża konfigurowalność
src: http://crest.codegist.org/
29. Pomocne biblioteki - CRest
Przykład
@EndPoint("http://api.twitter.com")
@Path("/1/statuses")
@Consumes("application/json")
public interface StatusService {
@POST
@Path("update.json")
Status updateStatus(
@FormParam("status") String status,
@QueryParam("lat") float lat,
@QueryParam("long") float longitude);
@Path("{id}/retweeted_by.json")
User[] getRetweetedBy(
@PathParam("id") long id,
@QueryParam("count") long count,
@QueryParam("page") long page);
@Path("followers.json")
User[] getFollowers(@QueryParam("user_id") long userId);
}
CRest crest = CRest.getInstance();
StatusService statusService = crest.build(StatusService.class);
User[] folowers = statusService.getFollowers(42213);
31. Pomocne biblioteki - CRest
Error handler
public class MyErrorHandler implements ErrorHandler {
@Override
public <T> T handle(Request request, Exception e) throws Exception {
if( e instanceof RequestException ) {
RequestException ex = (RequestException) e;
Response resp = ex.getResponse();
throw new ApiException( resp.to( com.rwozniak.api.entities.ErrorResponse.class ) );
}
return null;
}
}
public class ErrorResponse {
@SerializedName("http_code") public int httpCode;
public String error;
@SerializedName("error_title") public String errorTitle;
@SerializedName("error_description") public String errorDescription;
@SerializedName("validation_errors") public ArrayList<String> validationErrors;
}
32. Pomocne biblioteki - CRest
Dowolny deserializer
public class CustomGsonDeserializer implements Deserializer {
@Override
public <T> T deserialize(Class<T> tClass, Type type, InputStream inputStream, Charset charset) throws Exception {
GsonBuilder builder = new GsonBuilder();
JsonParser parser = new JsonParser();
JsonElement element = parser.parse( new InputStreamReader(inputStream) );
return builder.create().fromJson( element, type );
}
}
36. Persystencja i REST
Niewłaściwa implementacja
Activity 1. Get, create, update, delete CursorAdapter
Wątek
3. Przetwarzanie
Metoda REST Processor 5. Odświeżenie
4. Zapis
2. GET/POST/PUT/DELETE
Pamięć
37. Persystencja i REST
Niewłaściwa implementacja
• Proces aplikacji może zostać zabity przez system
• Dane nie są zapisywane na stałe (baza danych)
38. Persystencja i REST
Service API
Activity CursorAdapter
1. wywołanie 11. callback do Activity
8'. powiadomienie
ContentObervera 8''. requery
Service Helper
2. startService(Intent) 10. callback Bindera
Service
3. start(param) 9. callback wykonania
4. insert/update
Processor Content Provider
8. insert/update
5. start(param)
7. odpowiedź REST
Metoda REST
6. GET/POST/PUT/DELETE
39. Persystencja i REST
Processor - POST i PUT
POST
4. insert
(set STATE_POSTING)
Processor Content Provider
8. update
(clear STATE_POSTING)
Metoda REST
PUT
4. insert
(set STATE_POSTING)
Processor Content Provider
8. update
(clear STATE_POSTING)
Metoda REST
40. Persystencja i REST
Processor - DELETE i GET
DELETE
4. insert
(set STATE_DELETING)
Processor Content Provider
8. delete
Metoda REST
GET
Processor Content Provider
8. insert new resource
Metoda REST
41. Podsumowanie
O czym pamiętać
• operacje HTTP zawsze w osobnych wątkach (np.
IntentService)
• persystencja przed i po komunikacji
• minimalizacja ruchu HTTP (kompresja, nagłówki)
• zewnętrzne biblioteki - ułatwiają życie
• StackOverflow
wzorzec architektury oprogramowania dla rozproszonych systemów takich jak wwwRoy Fielding jednym z autorów specyfikacji protokołu HTTP
separacja widoku od bazy danych za pomocą interfejsu jakim jest RESTbrak sesji, każde żądanie zawiera wszystkei dane konieczne do jego wykonaniacache - klienci mogą cacheowac odpowiedz jezeli serwer wskaze ze mozna to zrobic, poprawa skalowalnosci i wydajnosciwarstwy - skalowalnosc, load balancinginterfejs - mozliwosc niezaleznego rozwoju klienta i serwisu
----- Meeting Notes (13.12.2012 14:14) -----get. put idempotent
idempotentna
idempotentna
If-Modified-Since - przy braku zmian serwer zwraca 304 (Not modified)
A connectiontimeoutoccursonly upon starting the TCP connection. Thisusuallyhappensif the remotemachinedoes not answer. Thismeansthat the serverhasbeenshut down, youused the wrong IP/DNS nameor the network connection to the serveris down.A sockettimeoutisdedicated to monitor the continuousincoming data flow. If the data flowisinterrupted for the specifiedtimeout the connectionisregarded as stalled/broken. Of coursethisonlyworks with connectionswhere data isreceivedall the time.
dla uproszczenia nie zamieszczam w kodzie bloków try-catch
moze pokazac kod calego factory?
wisinka na torcie, final, dodac obrazek
[wyrdźil dobdźanski] - software ingineer at Google, tworca pierwszego oficjalnego klienta Twittera