SlideShare uma empresa Scribd logo
1 de 43
Android i REST




Roman Woźniak
Roman Woźniak
SignlApps, Lead Android Developer


  roman@signlapps.com
  @wozniakr
Agenda

• REST – co to jest?
• REST – jak korzystać efektywnie
• Komunikacja HTTP na Androidzie
• Biblioteki usprawniające pisanie aplikacji
• Komunikacja HTTP i bazy danych
REST




          REST




imgsrc: https://sites.google.com/site/sleepasandroid/
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
REST – co to jest?




Cechy serwisu RESTful


• architektura klient-serwer
• bezstanowość
• cache odpowiedzi
• system warstwowy
• uniwersalny interfejs
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
REST – co to jest?




Operacje CRUD


                      POST    =   Create
                        GET   =   Read
                        PUT   =   Update
                     DELETE   =   Delete
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}]
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}
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}
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
          <
REST – więcej




REST - więcej

• kody HTTP odpowiedzi


• wykorzystanie nagłówków
REST – więcej




Kody odpowiedzi HTTP
• 2XX - poprawne
• 3XX - przekierowania
• 4XX - błąd klienta (request)
• 5XX - błąd serwera (response)
REST – więcej




Błędy
• 400 (Bad Request)
• 401 (Unauthorized)
• 403 (Forbidden)
• 404 (Not Found)
• 500 (Internal Server Error)
• 503 (Service Unavailable)
• 418 (I’m a teapot (RFC 2324))
REST – więcej




          Programista też człowiek




imgsrc: http://thefuturebuzz.com/wp-content/uploads/2011/10/data.jpg
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/
REST – więcej




Nagłówki
• Accept: application/json
     Accept: application/json            Accept: application/xml

     {                                   <user>
                "id":113,                     <id>113</id>
                "firstname":"Joanna",         <firstname>Joanna</firstname>
                "lastname":"Kowalska",        <lastname>Kowalska</lastname>
                "age":18                      <age>18</age>
     }                                   </user>

• If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
• ETag i If-None-Match: 12331-erfwe-123331
• Accept-Language: ES-CT
• Accept-Encoding: gzip
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
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);
}
Android i HTTP




Prosty GET
String url = "https://api.rwozniak.com/users/1303";
HttpGet httpGet = new HttpGet( url );
//setCredentials( httpGet );
//addHeaders( httpGet );
DefaultHttpClient httpClient = createHttpClient();

HttpResponse httpResponse = httpClient.execute( httpGet );
String responseContent = EntityUtils.toString( httpResponse.getEntity() );




{"id":131,"firstname":"Joanna","lastname":"Kowalska","age":18}
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;
                           }
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;
}
Android i HTTP




imgsrc: http://www.quickmeme.com/meme/3rxotv/
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/
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 );
}
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;
}
Pomocne biblioteki - CRest




           CRest

           • po prostu Client REST
           • ułatwia komunikację z serwisami typu RESTful
           • annotacje
           • duża konfigurowalność




src: http://crest.codegist.org/
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);
Pomocne biblioteki - CRest




Jednorazowa konfiguracja


CRestBuilder crestInstance = new CRestBuilder()
      .property( MethodConfig.METHOD_CONFIG_DEFAULT_ENDPOINT, "https://api.rwozniak.com/1.0" )
      .property( MethodConfig.METHOD_CONFIG_DEFAULT_ERROR_HANDLER, MyErrorHandler.class )
      .setHttpChannelFactory( HttpClientHttpChannelFactory.class )
      .placeholder( "auth.token", getUserAuthToken() )
      .deserializeJsonWith( CustomGsonDeserializer.class );
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;
}
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 );
    }
}
Pomocne biblioteki - CRest




Fabryka serwisów
public class ServiceFactory {

    private static CRestBuilder crestInstance;
    private static UserService userService;

    private static void init( boolean authenticated ) {
       crestInstance = new CRestBuilder(); // kod z poprzedniego slajdu...
    }

    private static CRestBuilder getInstance() {
       if( crestInstance==null ) {
           init();
       }
       return crestInstance;
    }

    public static UserService getUserService() {
      if( userService==null ) {
          userService = getInstance().placeholder( "userid", getUserId() ).build().build( UserService.class );
      }
      return userService;
    }
}
Pomocne biblioteki - CRest




Finał


User user = ServiceFactory.getUserService().create( "John", "Doe", 25 );

user.age = 32;
ServiceFactory.getUserService().update( user );

ServiceFactory.getUserService().delete( user.id );
Persystencja i REST




Persystencja i REST

Prezentacja z GoogleIO 2010
       – autor: Virgil Dobjanschi
       – źródło: http://goo.gl/R15we
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ęć
Persystencja i REST




Niewłaściwa implementacja

• Proces aplikacji może zostać zabity przez system


• Dane nie są zapisywane na stałe (baza danych)
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
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
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
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 
Pytania




          Pytania?




imgsrc: http://presentationtransformations.com/wp-content/uploads/2012/03/Question.jpg
Dziękuję




          Dziękuję




imgsrc: http://memegenerator.net/instance/29015891

Mais conteúdo relacionado

Semelhante a Android i REST

JSON, REST API
JSON, REST APIJSON, REST API
JSON, REST API3camp
 
Budowa RESTowego api w oparciu o HATEOAS
Budowa RESTowego api w oparciu o HATEOASBudowa RESTowego api w oparciu o HATEOAS
Budowa RESTowego api w oparciu o HATEOASMateusz Stępniak
 
W3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaW3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaBartosz Romanowski
 
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013Mateusz Stępniak
 
Paleta możliwości web developera
Paleta możliwości web developeraPaleta możliwości web developera
Paleta możliwości web developeraTomasz Borowski
 
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...PROIDEA
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaMaciej Ziarko
 
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Logicaltrust pl
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwLuke Adamczewski
 
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Polcode
 
Środowisko testowe pod REST-a
Środowisko testowe pod REST-aŚrodowisko testowe pod REST-a
Środowisko testowe pod REST-aFuture Processing
 
Optymalizacja aplikacji ASP.NET
Optymalizacja aplikacji ASP.NETOptymalizacja aplikacji ASP.NET
Optymalizacja aplikacji ASP.NETBartlomiej Zass
 
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaModsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaLeszek Mi?
 
WP-API - teoria i praktyka - WordUp Trójmiasto #2
WP-API - teoria i praktyka - WordUp Trójmiasto #2WP-API - teoria i praktyka - WordUp Trójmiasto #2
WP-API - teoria i praktyka - WordUp Trójmiasto #2Tomasz Dziuda
 
Krytyczne błędy konfiguracji
Krytyczne błędy konfiguracjiKrytyczne błędy konfiguracji
Krytyczne błędy konfiguracjiLogicaltrust pl
 
WP-API - teoria i praktyka - WordUp Łódź #4
WP-API - teoria i praktyka - WordUp Łódź #4WP-API - teoria i praktyka - WordUp Łódź #4
WP-API - teoria i praktyka - WordUp Łódź #4Tomasz Dziuda
 

Semelhante a Android i REST (20)

JSON, REST API
JSON, REST APIJSON, REST API
JSON, REST API
 
Budowa RESTowego api w oparciu o HATEOAS
Budowa RESTowego api w oparciu o HATEOASBudowa RESTowego api w oparciu o HATEOAS
Budowa RESTowego api w oparciu o HATEOAS
 
Platforma Kontentowa
Platforma KontentowaPlatforma Kontentowa
Platforma Kontentowa
 
W3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaW3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressa
 
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013
Budowa poprawnego i intuicyjnego api REST HATEOAS devfest@2013
 
Paleta możliwości web developera
Paleta możliwości web developeraPaleta możliwości web developera
Paleta możliwości web developera
 
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
 
HTML5: Atak i obrona
HTML5: Atak i obronaHTML5: Atak i obrona
HTML5: Atak i obrona
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
 
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
 
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
 
Środowisko testowe pod REST-a
Środowisko testowe pod REST-aŚrodowisko testowe pod REST-a
Środowisko testowe pod REST-a
 
Optymalizacja aplikacji ASP.NET
Optymalizacja aplikacji ASP.NETOptymalizacja aplikacji ASP.NET
Optymalizacja aplikacji ASP.NET
 
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaModsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
 
WP-API - teoria i praktyka - WordUp Trójmiasto #2
WP-API - teoria i praktyka - WordUp Trójmiasto #2WP-API - teoria i praktyka - WordUp Trójmiasto #2
WP-API - teoria i praktyka - WordUp Trójmiasto #2
 
Krytyczne błędy konfiguracji
Krytyczne błędy konfiguracjiKrytyczne błędy konfiguracji
Krytyczne błędy konfiguracji
 
WP-API - teoria i praktyka - WordUp Łódź #4
WP-API - teoria i praktyka - WordUp Łódź #4WP-API - teoria i praktyka - WordUp Łódź #4
WP-API - teoria i praktyka - WordUp Łódź #4
 
Wordpress i nagłówki
Wordpress i nagłówkiWordpress i nagłówki
Wordpress i nagłówki
 

Android i REST

  • 2. Roman Woźniak SignlApps, Lead Android Developer roman@signlapps.com @wozniakr
  • 3. Agenda • REST – co to jest? • REST – jak korzystać efektywnie • Komunikacja HTTP na Androidzie • Biblioteki usprawniające pisanie aplikacji • Komunikacja HTTP i bazy danych
  • 4. REST REST imgsrc: https://sites.google.com/site/sleepasandroid/
  • 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
  • 14. REST – więcej Kody odpowiedzi HTTP • 2XX - poprawne • 3XX - przekierowania • 4XX - błąd klienta (request) • 5XX - błąd serwera (response)
  • 15. REST – więcej Błędy • 400 (Bad Request) • 401 (Unauthorized) • 403 (Forbidden) • 404 (Not Found) • 500 (Internal Server Error) • 503 (Service Unavailable) • 418 (I’m a teapot (RFC 2324))
  • 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/
  • 18. REST – więcej Nagłówki • Accept: application/json Accept: application/json Accept: application/xml { <user> "id":113, <id>113</id> "firstname":"Joanna", <firstname>Joanna</firstname> "lastname":"Kowalska", <lastname>Kowalska</lastname> "age":18 <age>18</age> } </user> • If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT • ETag i If-None-Match: 12331-erfwe-123331 • Accept-Language: ES-CT • Accept-Encoding: gzip
  • 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); }
  • 21. Android i HTTP Prosty GET String url = "https://api.rwozniak.com/users/1303"; HttpGet httpGet = new HttpGet( url ); //setCredentials( httpGet ); //addHeaders( httpGet ); DefaultHttpClient httpClient = createHttpClient(); HttpResponse httpResponse = httpClient.execute( httpGet ); String responseContent = EntityUtils.toString( httpResponse.getEntity() ); {"id":131,"firstname":"Joanna","lastname":"Kowalska","age":18}
  • 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; }
  • 24. Android i HTTP imgsrc: http://www.quickmeme.com/meme/3rxotv/
  • 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);
  • 30. Pomocne biblioteki - CRest Jednorazowa konfiguracja CRestBuilder crestInstance = new CRestBuilder() .property( MethodConfig.METHOD_CONFIG_DEFAULT_ENDPOINT, "https://api.rwozniak.com/1.0" ) .property( MethodConfig.METHOD_CONFIG_DEFAULT_ERROR_HANDLER, MyErrorHandler.class ) .setHttpChannelFactory( HttpClientHttpChannelFactory.class ) .placeholder( "auth.token", getUserAuthToken() ) .deserializeJsonWith( CustomGsonDeserializer.class );
  • 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 ); } }
  • 33. Pomocne biblioteki - CRest Fabryka serwisów public class ServiceFactory { private static CRestBuilder crestInstance; private static UserService userService; private static void init( boolean authenticated ) { crestInstance = new CRestBuilder(); // kod z poprzedniego slajdu... } private static CRestBuilder getInstance() { if( crestInstance==null ) { init(); } return crestInstance; } public static UserService getUserService() { if( userService==null ) { userService = getInstance().placeholder( "userid", getUserId() ).build().build( UserService.class ); } return userService; } }
  • 34. Pomocne biblioteki - CRest Finał User user = ServiceFactory.getUserService().create( "John", "Doe", 25 ); user.age = 32; ServiceFactory.getUserService().update( user ); ServiceFactory.getUserService().delete( user.id );
  • 35. Persystencja i REST Persystencja i REST Prezentacja z GoogleIO 2010 – autor: Virgil Dobjanschi – źródło: http://goo.gl/R15we
  • 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 
  • 42. Pytania Pytania? imgsrc: http://presentationtransformations.com/wp-content/uploads/2012/03/Question.jpg
  • 43. Dziękuję Dziękuję imgsrc: http://memegenerator.net/instance/29015891

Notas do Editor

  1. wzorzec architektury oprogramowania dla rozproszonych systemów takich jak wwwRoy Fielding jednym z autorów specyfikacji protokołu HTTP
  2. 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
  3. ----- Meeting Notes (13.12.2012 14:14) -----get. put idempotent
  4. idempotentna
  5. idempotentna
  6. If-Modified-Since - przy braku zmian serwer zwraca 304 (Not modified)
  7. 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.
  8. dla uproszczenia nie zamieszczam w kodzie bloków try-catch
  9. moze pokazac kod calego factory?
  10. wisinka na torcie, final, dodac obrazek
  11. [wyrdźil dobdźanski] - software ingineer at Google, tworca pierwszego oficjalnego klienta Twittera