API

Interfejs Programistyczny Aplikacji

1 grudnia 2015 21:00
Piotr Bajsarowicz
python development api

Historia pewnego programisty

Pewien programista, po kilku latach nauki programowania w Pascalu, C++, C, Javie, Pythonie, po wielu godzinach spędzonych twarzą w twarz z czarno-białą konsolą swojego IDE postanawia wreszcie wykorzystać zdobytą wiedzę. Wybór pada na Aplikacje internetowe! Dobry pomysł... w końcu szansa na zobaczenie rezultatów swojej pracy w więcej niż tylko dwóch kolorach. Nasz bohater przystępuję do googlowania. Dowiaduje się, w jakich językach może pisać, jak dokładnie działa usługa WWW, zaznajamia się z protokołem HTTP. Zaczyna dostrzegać różnicę pomiędzy zasłyszanymi wcześniej pojęciami - front-endem a back-endem, odnajduje pojęcie framework. Wszystko idzie jak z płatka. Do czasu. API. No cóż, pewien programista słyszał o nim wcześniej ale właściwie nie zastanawiał się czym jest. Zatem, analogicznie do wcześniejszych kroków szuka. Odnajduje, że jest to skrót od Application Programming Interface, czyli Interfejs Programistyczny Aplikacji. Niezła abstrakcja. Na szczęście jest definicja.

API to sposób, rozumiany jako ściśle określony zestaw reguł i ich opisów, w jaki programy komputerowe komunikują się między sobą. API definiuje się na poziomie kodu źródłowego dla takich składników oprogramowania jak np. aplikacje, biblioteki czy system operacyjny.

Ok, ok... to czym jest to API?

API to zbiór procedur, protokołów, narzędzi do budowania aplikacji. Definiuje sposób, w jaki poszczególne komponenty aplikacji powinny oddziaływać na siebie wzajemnie.

I to scenariusz, który powtarza się 234 621 643 razy w roku (dane nieoficjalne, nieznanego pochodzenia).

Jak żyć?

Żeby dobrze zrozumieć to pojęcie należy przeanalizować skrót, rozłożyć go na czynniki pierwsze: Interfejs, Programistyczny, Aplikacji. Część Programistyczny wydaje się być oczywista dlatego, że, jak mówi teoria, API definiuje się na poziomie kodu źródłowego. Ale Interfejs Aplikacji? Hm...

Aplikacja

Co mamy na myśli mówiąc aplikacja? Coś na nasz komputer, telefon, tablet itd. W tym przypadku pomyślmy o API jako o maszynie. Co robi maszyna? Wykonuje swoje specyficzne zadania, do których została zaprojektowana. Dla kogo? Dla nas.

Dla lepszego zrozumienia posłużymy się przykładem. Przyjmijmy, że API to telewizor (dla uproszczenia tematu przyjmiemy, że mamy do czynienia z telewizją analogową).

Zatem... co robi dla nas telewizor? Załóżmy, że kupiliśmy telewizor jak na załączonym obrazku. Co z nim robimy? No... podłączamy kabel analogowy do telewizora, dając mu tym samym sygnał, czyli inaczej mówiąc dostarczamy mu pewne źródło danych, które potrafi przetworzyć i w reakcji, na które potrafi wyświetlić pewien obraz. Ok... Ale jak wyświetla? Co wyświetla? Czy mamy nad nim kontrolę? Jasne!

Bierzemy pilot, wybieramy odpowiedni kanał wciskając jeden z dostępnych przycisków i wysyłamy sygnał do telewizora. Sygnał ten jest przez telewizor odpowiednio interpretowany i w rezultacie wyświetlony zostaje kanał, którego oczekiwaliśmy.

Innymi słowy, za pomocą pilota wybieramy określony przycisk, wysyłamy pewne, zrozumiałe dla telewizora dane, on następnie je przetwarza i reaguje w oczekiwany przez nas sposób.

Czyli wszystko co robi ta maszyna to:

  1. Przyjmuje dane.
  2. Odpowiednio je interpretuje
  3. Zwraca dane.

Wszystko o co musimy się zatroszczyć to odpowiednie dane na wejściu. Resztę wykona maszyna dając nam odpowiednie dane na wyjściu.

Czyli de facto stajemy przed jakimś problemem, który rozwiązuje maszyna. Problem: chcemy przełączyć kanał. Rozwiązanie: odpowiedni przycisk na pilocie ⇒ oczekiwany kanał na TV.

No ok… ale jak ma się to do Internetu?

Podobnie jak telewizor wykonuje dla nas jakieś zadanie, rozwiązuje nasz problem, tak samo aplikacje internetowe wykonują dla nas zadania, o które je poprosimy. Jako przykładem posłużymy się popularnym portalem społecznościowy Facebook. Każdy z nas ma znajomych, którzy ochoczo dzielą się każdą chwilą ze swojego ciekawego życia. Posłużmy się ich przykładem. Powiedzmy, że rodzina Sapkowskich wróciła z wakacji. Oczywiście ich znajomi pragną zobaczyć wszystkie zdjęcia, tylko czekają aż je wrzucą (problem - czekający znajomi) więc rodzina zabiera się za ich zadanie. Podają opis zdjęcia, wybierają konkretny plik i wysyłają do Facebooka (przykład z telewizorem ⇒ sygnał wysłany przez pilot). On analizuje dane, odpowiednio je interpretuje i w wyniku zdjęcie ląduje na ich tablicy, dzięki czemu znajomi mogą lajkować i komentować do woli. Problem rozwiązany.

Ale czy mogą robić to tylko na jednym, konkretnym komputerze? No nie. Treść, która została właśnie dodana może być wyświetlana na monitorze każdego komputera, w oknie każdej przeglądarki (no… może na IE będą jakieś problemy), na ekranie telefonu, tabletu. Czyli wysyłając odpowiednie dane w jednym miejscu możemy zobaczyć dane wyjściowe wszędzie tam, gdzie pozwala nam na to dana aplikacja. Innymi słowy - jedna aplikacja - wielu klientów.

To co pozwala nam na taką multiplatformowość (w pewnym uproszczeniu) to właśnie API. Każdy klient aplikacji odpytując o konkretne dane otrzymuje te same wyniki. Klient (np. nasza aplikacja webowa) sam w sobie nie generuje tych danych. Odpytuje API i otrzymuje wyniki.

Interfejs

Najprościej mówiąc interfejs to sposób w jaki aplikacja przyjmuje dane i sposób w jaki oddaje wyniki. W naszym przypadku interfejsem jest pilot.

My wybieramy odpowiedni przycisk na pilocie i pilot sam wie jaki sygnał sygnał wysłać, żeby na ekranie naszego telewizora pojawił się kanał, który chcemy zobaczyć. Czyli nie wiemy tak naprawdę co pilot zrobił i jak zareagował na to telewizor. Mimo tego w bardzo łatwy sposób możemy wytłumaczyć drugiej osobie co powinna zrobić, żeby przełączyć kanał. Dzięki takiemu interfejsowi funkcja przełączania kanałów jest tak prosta.

Facebook również korzysta z interfejsu, tzn. oczekuje, że wyślemy mu konkretnie zapytanie a w zamian odeśle nam wyniki, których my oczekujemy.

Czyli co? Właściwie po prostu wysyłamy zapytanie na adres url, więc równie dobrze możemy użyć naszej przeglądarki jak i aplikacji mobilnej. Idziemy zawsze na ten sam adres oczekując tych samych danych. URL i otrzymane dane są ustandaryzowane. Tzn., że wysyłamy zapytanie na adres i z argumentami, które Facebook potrafi zinterpretować i otrzymujemy wyniki w formie, którą dostarcza Facebookowe API. Ustandaryzowany interfejs, który sprawia, że człowiek może rozmawiać z aplikacją.

Oznacza to tyle, że dzięki API możemy napisać aplikację, która będzie rozmawiała z Facebookiem. Co ważne - Facebook nie musi się bać o to jaki klient będzie używał ich API. Wystawia swój zestaw reguł, ustandaryzowany interfejs i pozwala na komunikację ze sobą w z góry określony sposób.

Dlaczego API jest ważne dla developerów?

Każda strona rozwiązuje określony problem, daje funkcjonalność, np.

  • Facebook umożliwia kontakowanie się ze znajomymi, czatowanie z nimi, wymienianie się zdjęciami, etc.
  • Google pozwala nam wyszukiwać informacje w Internecie.
  • Spotify pozwala nam na znalezienie muzyki i odsłuchanie muzyki.

W każdym przypadku wyniki otrzymujemy natychmiast po odpytaniu API.

Ok… ale co to ma do wszystkich developerów? A no to, że jeśli API jest wystawione publicznie to możemy z niego korzystać w swoich aplikacjach. I tak np. dzięki Google maps, nie potrzebujemy zabierać się za trudne zadanie stworzenia mapy miejsca, które musimy zamieścić w naszej aplikacji. Wystarczy skorzystać z wystawionego publicznie Google Maps API i mamy dostęp do każdej lokalizacji na ziemi - spójrzcie na przykłady:

  • http://www.flightradar24.com/
  • http://www.oldmapsonline.org/
  • http://www.class3outbreak.com/

Metody HTTP

Rozróżniamy 9 metod HTTP: GET, HEAD, PUT, POST, DELETE, OPTIONS, TRACE, CONNECT, PATCH

Do omówienia działania API wystarczy nam pięć najpowszechniejszych:

  • GET - pobranie zasobu wskazanego przez URI
  • PUT - aktualizacja wartości
  • POST - Tworzenie nowego zasobu
  • DELETE - Usunięcie istniejącego zasobu
  • PATCH - częściowa aktualizacja

Przykłady użycia

  • POST /book/add - utwórz zasób book
  • DELETE /book/del/1 - usuń zasób book o id = 1
  • GET /book/get/1 - pobierz zasób book o id = 1

(Powyższe przykłady w oparciu o REST API).

POST vs GET vs PUT

  • POST nie jest idempotentny (unsafe).
  • GET jest idempotentny (safe).
  • PUT jest idempotentny (safe).

Idempotentność to właściwość pewnych operacji, która pozwala na ich wielokrotne stosowanie bez zmiany wyniku.

Kilka słów o SOAP i REST

SOAP i REST to dwie odpowiedzi na to same pytanie: w jaki sposób uzyskać dostęp do usług internetowych (ang. web services)?

SOAP

SOAP (ang. Simple Object Access Protocol) – protokół wywoływania zdalnego dostępu do obiektów, wykorzystujący XML do kodowania wywołań i najczęściej protokołów HTTP lub RPC do ich przenoszenia.

REST

REST (ang. Representational State Transfer (zmiana stanu poprzez reprezentacje)) – styl architektury albo wzorzec projektowy używany jak zbiór wytycznych do tworzenia web serwisów pozwalający na komunikację pomiędzy urządzeniami/aplikacjami podpiętymi do internetu poprzez współdziłdzielony protokół komunikacyjny HTTP.

XML vs JSON

Serializacja instancji klasy Person:

JSON

{ 
    "person": {
        "firstName": "Homer",
        "lastName": "Simpson",
        "relatives": [ "Grandpa", "Marge", "The Boy", "Lisa" ]
    }
}

XML

<Person>
    <FirstName>Homer</FirstName>
    <LastName>Simpsons</LastName>
    <Relatives>
        <Relative>Grandpa</Relative>
        <Relative>Marge</Relative>
        <Relative>The Boy</Relative>
        <Relative>Lisa</Relative>
    </Relatives>
</Person>

Jak działa API?

Podstawową różnicą pomiędzy REST a SOAP jest sposób dostępu do usług. W REST każda z usług opisania jest osobnych adresem URL. W SOAP dostęp do usług otrzymujemy (zwykle) pod jednym adresem URL, pod którym znajduje się opis wszystkich usług z wykorzystaniem specjalnego języka WSDL. Aby wykonać zapytanie (ang. request) w REST minimalnie wymagany jest adres URL, w SOAP każde opisane jest językiem XML o specjalnej (oczekiwanej) strukturze.

REST

Użytkownik za pomocą klienta (np. przeglądarki) wpisuje odpowiedni adres URL i z wykorzystaniem protokołu HTTP (lub HTTPS) wysyła zapytanie HTTP (odpytuje serwer). Serwer, pod warunkiem poprawności wysłanych danych, zwraca oczekiwaną odpowiedź HTTP, wraz z odpowiednim statusem (kodem odpowiedzi HTTP).

Powiedzmy, że chcemy dowiedzieć się ile lajków ma aktualnie fanpejdż STX Next. Wysyłamy zatem konkretne zapytanie i otrzymujemy oczekiwany wynik, konkretny rekord z bazy danych, w której znajdują się miliardy użytkowników. Wszystko dzięki API.

Budowa URL

Action - wskazuje konkrety punkt końcowy (ang. endpoint). Innymi słowy mówi API co chcemy zrobić, o co chcemy zapytać. W tym przypadku chcemy chcemy otrzymać dane dotyczące fanpejdżu o nazwie StxNext

Parametr - pozwala precyzować (zawężać) wyniki. Innymi słowy mówi API jakie informacje, jakie pola nas interesują. W przykładzie interesują nas wyłącznie lajki.

Wartość - precyzujemy, że chodzi nam o liczbę lajków.

Czyli nasz url mówi:

cześć API, pobierz dla mnie z bazy dane dotyczące fanpejdżu STX Next, ale zwróć tylko lajki.

Facebook, w celu wyświetlenia liczby lajków wykonuje dokładnie to samo zapytanie.

SOAP

WSDL (ang. Web Services Description Language) - oparty na XML język do definiowania usług internetowych.

Service Consumer - [Request] formułuje wiadomość (zapytanie) do Providera używając XML, bazując na specyfikacji zdefiniowanej w WSDL.

Service Provider - [Response] formułuje odpowiedź na zapytanie i wysyła ją do Consumera, również używając XML, bazując na specyfikacji zdefiniowanej w WSDL.

Budowa URL

Budowa WSDL

Poniżej znajduje się przykładowy plik WSDL implementujący endpoint GetBookPrice (dokładniej GetBookPrice (request) oraz GetBookPriceResponse (response)), pozwalający na odpytanie API o cenę danej książki, podając jej nr ISBN, tytuł (Title) oraz liczbę stron (NumPages). WSDL:

<wsdl:types>
  <xsd:schema targetNamespace="http://namespaces.my-example-book-info.com"
    xmlns:xsd="http://www.w3.org/1999/XMLSchema">
    ...
    <xsd:element name="GetBookPrice">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="ISBN" type="string"/>
          <xsd:element name="Title" type="string"/>
          <xsd:element name="NumPages" type="integer"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>
    ...
    <xsd:element name="GetBookPriceResponse">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="CurrentPrice" type="decimal" />
          <xsd:element name="Currency" type="string" />
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>
    ...
  </xsd:schema>
</wsdl:types>

Request:

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <m:GetBookPrice xmlns:m="http://namespaces.my-example-book-info.com">
      <ISBN>978-0451524935</ISBN>
      <Title>1984</Title>
      <NumPages>328</NumPages>
    </m:GetBookPrice>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

Response:

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <m:GetBookPriceResponse xmlns:m="http://namespaces.my-example-book-info.com">
      <CurrentPrice>8.99</CurrentPrice>
      <Currency>USD</Currency>
    </m:GetBookPriceResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Podsumowanie wykładu

API

Źródła i przydatne linki

Część praktyczna

Na zajęciach realizowaliśmy dwa zadania bazujące na RESTowym API serwisu GitHub.com z wykorzystaniem pythonowej biblioteki requests.

Przykładowe rozwiązania oraz wynik demo dostępne pod poniższym linkiem: http://goo.gl/AWv0r2

Przykładowe uruchomienie programu:

cd /path/to/downloaded/files
python task_1.py

Id: 6014599
Login: a
Name: Ampersand
Created at: 2013-11-22T23:55:04Z

Jak wygenerować token dla własnego konta: https://help.github.com/articles/creating-an-access-token-for-command-line-use/

W przypadku pytań o if __name__ == '__main__':: http://stackoverflow.com/questions/419163/what-does-if-name-main-do

Zadanie domowe

Zapisz na dysku zawartość pliku gista o id = 1 (https://api.github.com/gists/1)

Poprawny wynik działania programu to zapis pliku gistfile1.txt.

Zadanie w formie programu, w pliku o nazwie imie_nazwisko_grupaN.py (np. john_lennon_grupa1.py) proszę przesłać na adres piotr.bajsarowicz@stxnext.pl.

Tytuł maila: [API GRN] Imię Nazwisko (np. [API GR2] John Lennon).

Termin nadsyłania zadania:

  • Grupa poniedziałkowa - do 6.12 godz 23:59
  • Grupa wtorkowa - do 7.12 godz 23:59

Pytania?

Zapraszamy do zadawania pytań mailowo, na jeden z poniższych adresów:

  • artur.grochowski@stxnext.pl,
  • piotr.bajsarowicz@stxnext.pl.

Pamiętajcie, że Nie ma głupich pytań, są tylko głupie odpowiedzi.

Related pages

Comments