Moving Menu

Dostęp do Rails API z poziomu C++ [Część 1: zapytania GET]

corner Michał Brodecki
Michał Brodecki
2015-05-07
corner Dostęp do Rails API z poziomu C++ [Część 1: zapytania GET]
W trakcie mojej pracy napotkałem potrzebę komunikacji pomiędzy aplikacjami napisanymi w Ruby on Rails a desktopowymi programami napisanymi w C++ (z wykorzystaniem biblioteki QT). Zbudowanie odpowiedniego rozwiązania wiązało się z kilkoma czasochłonnymi problemami. Dla tego postanowiłem przedstawić Wam kilka sztuczek, które pozwolą zaoszczędzić czas. :) Zamiast tworzyć jeden wielki wpis, podzieliłem temat na części. W pierwszej z nich przedstawię Wam podstawy tworzenia zapytań GET.

Zapytania GET pozwalają na wyciąganie informacji z serwera. Jeżeli dane tam są serwer powinien je zwrócić. Bardziej oficjalną definicję znajdziecie tutaj.

Zatem do dzieła!

Pokażę Wam tylko część kodu, całość możecie znaleźć na githubie (kod aplikacji C++, kod Rails Api). Kiedy będziecie mieli wszystko przygotowane trzeba skompilować aplikację C++ i odpalić 'rails server'.

Teraz wystarczy wpisać http://localhost:3000/entries/1 i wcisnąć przycisk 'Send request' - wasze pierwsze zapytanie GET jest gotowe. A wygląda to tak:

 Przyjrzyjmy się bliżej kodowi

Przykład wysyłania zapytania GET w C++ wygląda następująco:

QNetworkAccessManager * manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this,  SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl(ui->urlLineEdit->text())));

QnetworkAccessManager jest klasą zaprojektowana do wysyłania zapytań sieciowych. Wywołując manager->get(QNetworkRequest(QUrl(ui->urlLineEdit->text()))); uzyskamy zapytanie dla odnośnika wziętego z paska adresu. Wraz z odpowiedzią QnetworkAccessManager wysyła sygnał 'Finished', który w moim przykładzie wiąże się ze slotem replyFinished.

Przykład otrzymywania odpowiedzi w C++:

void MainWindow::replyFinished(QNetworkReply * reply)
{
    ui->debugTextBrowser->append(tr("got reply"));
    QVariant statusCodeV =
    reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    ui->debugTextBrowser->append("Status code: " + QString::number(statusCodeV.value()));
    // Or the target URL if it was a redirect:
    QVariant redirectionTargetUrl =
    reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    // see CS001432 on how to handle this
    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = reply->readAll();
        QString string(bytes);
        ui->resultTextBrowser->setText(string);
    }
    else
    {
        //handle errors
    }
    reply->deleteLater();
}

Jak widać odpowiedź uzyskujemy w formie QByteArray, którą można łatwo przetworzyć na QString używając konstruktora. Pamiętajcie, że ten kod nie wskaże błędów w połączeniu, a w zastosowaniach produkcyjnych powinien. Szczegółowe informacje o błędach można przekazać użytkownikom używając reply -> error() - przykład znajdziecie tutaj.

Zwróćcie uwagę, że w momencie wyzwalania slotu dziedziczy on odpowiedź obiektu, za ten slot jest odpowiedzialny za usunięcie odpowiedzi. Nie powinnismy usuwać jej bezpośrednio poprzez użycie funkcji delete reply, zamiast tego zalecane jest użycie deleteLater. Możemy uzyskać więcej szczegółów na temat samej odpowiedzi poprzez wywołanie reply->attribute<T>(QNetworkRequest::Attribute code). Na przykład możemy uzyskać status kodu poprzez wywołanie statusCodeV.value<int>() - pamiętajcie, że to jest metoda szablonu, dlatego należy zapewnić typ zwracanych danych. Pełną listę atrybutów QNetworkReply można znaleźć na stronie.

Podsumowanie

Wpis ten poruszył podstawy zapytań GET w języku C++. W następnym wpisie pokażę w jaki sposób przygotować format JSON w aplikacji RoR, jak go pobrać z wykorzystaniem metody GET oraz jak go parsować i wydobywać dane. Dziękuję za uwagę.

 

BinarApps

Wpis został opublikowany dzięki współpracy z firmą BinarApps. Więcej wpisów o Ruby znajdziesz na ich blogu www.binarapps.com/blog

comments powered by Disqus

Powiązane

photo corner
Pięć najlepszych gemów Ruby, które pokochasz!

Każdy programista jest inny - każdy posiada swój ulubiony edytor kodu i system operacyjny. Każdy słucha innego rodzaju muzyki w czasie pracy, bądź nie słucha jest wcale. Pomimo różnych osobowości i preferencji wszyscy posiadamy jedną wspólną rzecz, która nazywa się "Gemfile". Po przejrzeniu moich ostatnich kilku projektów zauważyłem, że kilka gemów powtarza się dla każdej z aplikacji. Chciałbym przedstawić Wam pięć gemów, które pokochacie.

Czytaj więcej
photo corner
Dostęp do Rails API z poziomu C++ [Część 2: Parsowanie formatu JSON]

W moim ostatnim wpisie stworzyłem prostą metodę GET. Teraz pokażę w jaki sposób przygotować Railsy do wysyłania odpowiedzi JSON po stronie serwera oraz w jaki sposób parsować je wewnątrz aplikacji C++.

Czytaj więcej
photo corner
Dostęp do Rails API z poziomu C++ [Część 3: Zapytania POST]

W moich ostatnich dwóch wpisach omówiłem zapytania GET oraz parsowanie formatu JSON. W tym wpisie chciałbym pokazać, w jaki sposób przygotować zapytanie POST i stworzyć wpis wewnątrz naszej aplikacji Ruby.

Czytaj więcej