ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 29
Abonament PDF

Share Cluj - Jurnal tehnic

Silvia Răusanu
Software Developer
@ISDC



PROGRAMARE

Cum am ajuns în proiectul Share Cluj

Am auzit prima data de Share Cluj când încă era în stadiul de idee, când echipa încă lucra să clarifice scopul proiectului, se gândea cum să implice mai multă lume și cum să pună Clujul pe harta lumii. Inițial, rolul meu în proiect era de a fi un ambasador al Clujului, însă participând la o ședință de proiect și având pe masa de discuție partea tehnică a proiectului, am devenit imediat un membru al echipei.

Latura tehnică consta în a construi o platformă care să poată susține concursul din cadrul proiectului: orice persoană din Cluj și nu numai să promoveze Clujul în călătoriile sale, fie ele concedii sau delegații, împărtășind poveștile lor despre Cluj cu toți cei care încă nu au auzit de Cluj, și apoi să încarce pe rețelele sociale "dovada": o fotografie a mesajul "#sharecluj" în fiecare locație. Provocarea tehnică pe care am văzut-o eu a fost agregarea pe baza hashtag-ului "#sharecluj" (dorit în mesajul post-ului) a feed-urilor de pe Facebook, Twitter, Instagram și prezentarea lor pe site-ul proiectului www.sharecluj.com.

Prima soluție

Nu am fost atât de încântată când am descoperit că există platforme/site-uri care pot face acea agregare, însă tot aveam ocazia să le studiez și să aleg opțiunea cea mai bună pentru nevoile proiectului: să expună un API ce să conțină feed-ul cu pozele concurenților de pe rețelele sociale. Am analizat ce oferă Rignite, Hashtagr, TINT, TagBord. Nici una dintre acestea nu expunea API-ul pe care mi-l doream, însă fiind servicii plătite, am presupus că se poate discuta cu cei care întrețin platformele și se poate găsi o soluție pentru a reuși o integrare cât mai rapidă și o lansare a proiectului cât mai curând posibil.

Era deja luna iunie, iar noi ne doream ca până în iulie să dăm drumul la concurs. În așteptarea răspunsurilor de la Rignite și TINT, am început să fac teste pentru anumite hashtag-uri pe care le tot vedeam în feed-ul personal de Facebook. Lucrurile nu erau prea roz, nu prea găseam nimic din ce mă așteptam, nici nu se punea problema de a găsi tot - cum ai putea ține un concurs dacă unii concurenți sunt înscriși și alții nu? Așadar, pe lângă integrarea încă sub semnul întrebării cu site-ul sharecluj.com, o altă situație mult mai dificilă se întrezărea: nu puteam folosi nici unul dintre serviciile existente. Deci trebuia să facem totul de la zero!

Soluția "adevărată"

Când termenul propus era din ce în ce mai aproape, iar partea tehnică nu era nici pe-departe rezolvată, vă puteți imagina că nu eram prea fericită și nici prea încrezătoare că aș putea să termin tot singură în așa scurt timp. Supărată cum eram, am mers la serviciu și, cu jumătate de gură, mi-am întrebat colegii - pe Călin, Dan și Răzvan - dacă vor să facă voluntariat tehnic. Nu știu dacă starea mea de spirit i-a convins sau dacă și ei au văzut aceeași provocare pe care am văzut-o eu inițial, dar cert e faptul că doar în 10 minute ne-am stabilit o întâlnire la Dan, pe seară, la un pahar de vin, să ne facem un plan cum implementăm sharecluj.com. Până seară, ne-am făcut rost și de specificații funcționale de la Alina, care din manager de proiect s-a transformat instant în product owner.

Chiar dacă tentația e mare să experimentezi cu tehnologii noi când ai pe mână un proiect green field, ne-am decis rapid să folosim ca tehnologie de bază Java și framework-uri cunoscute: Spring MVC, JDO. Costul proiectului trebuia să fie cât mai mic posibil, deci nu se putea pune problema închirierii unui server, așa că am ales ceva ce nu am mai folosit până atunci: Google AppEngine cu o quota suficient de mare pentru stocare de date, operațiuni pe baza de date, ore de instanță, indecși, deploy-uri, etc. . AppEngine s-a dovedit a fi cel mai potrivit pentru proiect. Integrarea cu rețelele sociale urma să fie făcută folosind API-ul expus de fiecare prin scrierea de clienți care să aducă metadata post-urilor și să o stocheze în baza de date.

Implementarea

Pentru a ne asigura că vom reuși să terminăm tot ceea ce product owner-ul, Alina, ne-a cerut, am împins termenul limită către începutul lui august. Implementarea fiecărui punct s-a făcut prioritizat, în funcție de riscul pe care credeam noi că îl poate reprezenta.

Aplicațiile web bazate pe Java și Spring MVC nu reprezintă o noutate pentru echipa nou formată, așa că primul pas a fost investigația GraphAPI-ului oferit de Facebook - Facebook, fiind cea mai folosită rețea socială în România (deci și cea mai relevantă pentru proiect), dar și platforma care era cel mai rar regăsită în rezultatele testelor pe agregatoarele de hasgtag-uri, prezenta cel mai mare risc. De vreme ce exista posibilitatea de căuta din aplicația Facebook după un hashtag, aveam așteptări foarte mari de la GraphAPI ca acesta să-mi ofere exact ceea ce îmi doream: post-urile cu hashtag-ul "#sharecluj". Dar nici vorbă de așa ceva! Am aflat de alternativa de a folosi API-ul de search pentru cuvinte cheie, folosind hashtag-ul; căutarea funcționa după reguli bizare, unele post-uri apăreau printre rezultate, altele nu. Am făcut experimente pe contul personal: am postat mesaje de test conținand "#sharecity" (nu voiam să stric lansarea); am așteptat o zi, o săptămână să îmi apară - nimic; în plus, în scurt timp, API-ul urma să devină obsolete și retras. ( Nu mai este accesibil la momentul de față). În căutările după explicații, am dat peste secțiunea FAQ de la TINT, unde precizau că pentru a avea întregul feed este necesar un workaround și anume ca utilizatorii să posteze pe o pagină de Facebook sau să eticheteze (tag) un utilizator pe conținut. Nu tocmai cea mai "profi" soluție, însă am fost de acord toți că era singura.

O veste bună din zona Facebook a fost că pentru autentificare aveau OAuth2 și că se putea face și offline, dintr-u cron job - așa cum intenționam și noi. Peste GraphAPI s-au scris suficienți clienți Java, dintre care am ales RestFB - ușor de folosit și extensibil.

După experiența cu Facebook, așteptările generale față de orice API au scăzut; însăTwitter avea ceea ce ne doream: un API simplu, bazat pe hashtag. Conform descrierii endpoint-ului, Twitter nu garantează că absolut toate tweet-urile cu un hashtag vor fi returnate, deoarece se face automat o filtrare în funcție de relevanță/popularitate; alternativa oferită este de a ne lega și "asculta" la stream-ul public. În acest caz a apărut o altă dificultate: dacă alegeam stream-ul însemna că am avea nevoie de încă o instanță în AppEngine - ceea ce ar fi întrecut limitele gratuității. Luând în considerare și costul, dar și o eventuală consistență în procedură, am ales să folosim API-ul pentru mentions (un utilizator să fie menționat în tweet). Din fericire, integrarea a fost simplă: am folosit un client Java pentru API-ul Twitter: Twitter4j.

Instagram a fost integrat mai tarziu față de celelalte rețele, iar soluția nu a avut nevoie de nici o concesie. Am fost încântată să observ că au un API per hashtag, nefiltrat, singura limitare fiind la numărul de rezultate - la fiecare apel se returnează cel mai nou conținut și nu se reține starea completă (prin API) a tuturor post-urilor. Pentru Instragram, nu sunt atât de mulți clienți, însă cel ales, jInstagram, a fost suficient. În ceea ce ține de autentificare, și Instagram implementează OAuth2, însă nu se poate folosi și offline (pentru cron job), dar exact API-ul utilizat ( /tags/{tag}/media/recent) se putea folosi doar pe baza unui _clientid.

Mi-a plăcut să fac cunoștință cu întregul ecosistem Java din AppEngine - am putut să folosesc fără probleme toate framework-urile dorite. În primul rând, nu a trebuit să-mi fac griji că acest cod ar putea deveni public înainte să fie ceva cu adevărat valoros - pentru fiecare aplicație există un Git repo, nu se poate clona direct, ci prin SDK-ul corespunzător. Apoi, pentru integrare cu Maven, există atât un plugin pentru management, cât și un arhetip pentru proiecte web. Pentru interacțiunile cu baza de date se poate folosi atât JPA, cât și JDO la fel de ușor (am ales JDO). De asemenea, suportul pentru cron jobs este inclus, având ca premise existența unui serviciu REST pentru execuție și un fișier de configurare. Aplicația web construită cu Spring MVC expune servicii REST atât pentru a culege datele din rețelele sociale, cât și pentru a face datele accesibile pentru interfața web. Toate datele afișate se aduc asincron, prin apeluri de Ajax.

Lansarea

După toate problemele întâmpinate în locuri neașteptate, dar și "ajutorul" din partea tool-urilor bine făcute, am ajuns la următorul design, care a fost lansat pe 4 august, exact la termen.

Imediat după lansare, aproape întreaga echipă de dezvoltare a plecat în concediu. Nimic grav nu s-a întâmplat pentru că aplicația era stabilă,deși nu am avut un tester oficial în echipă. Însă, între timp, Facebook a lovit din nou! Pe măsură ce proiectul devenea tot mai cunoscut și poze cu "#sharecluj" erau upload-ate în diverse forme, descopeream tot mai multe probleme și lacune în API-ul Facebook-ului: unele poze, deși urmau întreaga procedură, nu erau returnate de serviciu. Am declarat în august un defect care abia la sfârșitul lui octombrie a fost rezolvat, dar nu complet, încă sunt concurenți care nu au fost înregistrați pe platformă - drept urmare, am declarat un nou bug.

Unde suntem acum

După trei luni de când proiectul a fost lansat, aplicația este în continuare stabilă. Bineînțeles, ajustări minore au fost făcute pentru a corecta scăpări sau pentru a completa informații. A fost și va continua să fie până în octombrie 2015, o experiență foarte interesantă; nu credeam niciodată că voi ajunge să cunosc într-atât de aproape rețelele sociale sau că voi descoperi defecte la Facebook sau că voi face deploy-uri în producție de pe canapeaua de acasă.

În concluzie, mă bucur că am contribuit la proiectul Share Cluj și că am reușit să punem deja Clujul pe harta lumii în 36 de țări, printre care unele foarte exotice: Senegal, Singapore, Puerto Rico, Australia. Haideți să continuăm să "Share Cluj"!

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects