Julkaisimme TKrekryn lähdekoodit viime viikolla avoimena GitHubiin ja tämän kepin johdosta bloggaaja on ajettu taas sorvin ääreen. Valotan seuraavassa Tkrekryn toimintaa tekniseltä näkökantilta ja jaan joitakin havaintoja mitä matkalla tehtiin.
Teknologiavalintoja ja arkkitehtuuria
Ennen kuin päätös TKrekryn uudistamisesta oli tehty, olimme Jaakon kanssa puntaroineet jo useaan kertaan sitä miten mahdollinen tuleva sivusto kannattaisi tehdä. Edellinen sivusto oli toteutettu Ruby on Rails pohjaisen Radiant CMS:n päälle, jonka kehitys näytti jossain vaiheessa kuolevan kasaan ja mm. tästä syystä sivuston teknologiapinon päivittäminen oli joka kerralla entistä haastavampaa. Vuosien saatossa asiakas ei ollut juurikaan käyttänyt julkaisujärjestelmää, vaan sisällön päivittäminen sivustolle oli ollut käytännössä HTML:ää puhuvan allekirjoittaneen heiniä. Koska ylläpitomalliin ei ollut näköpiirissä muutoksia, olimme epäluuloisia sen suhteen kannattaisiko uutta sivustoa rakentaa lainkaan valmiin julkaisujärjestelmätuotteen varaan. Tarvetta sisällönmuokkauskäyttöliittymälle ei olisi ja rajoittaisiko valmis softa liikaa käsiä vai taipuisiko se kustannustehokkaasti meidän ja käyttäjien tarpeisiin? Toinen kysymys oli se että, jos uutta sivustoa lähdettäisiin tekemään meidän voimin, niin haluaisimmeko edes vai tekisimmekö sivuston ns. skrätsistä.
En hetkeäkään epäile etteikö sivustoa olisi voinut toteuttaa valmiilla softalla ulkoisesti sellaiseksi, kuin millaisena se elokuussa julkaistiin. Näin varmasti olisi tehtykin, jos päivätöinämme toteuttaisimme sivustoja WordPressillä, Drupalilla tms., koska työ olisi tietenkin ollut nopeaa ja alustan mahdollisuudet ja rajoitteet hyvin tiedossa. Meillä sen sijaan olisi ollut useamman päivän tutkimusmatka edessä selvittääksemme miten valitulla alustalla toteutus olisi kannattanut tehdä sen parhaita kehitys- ja laajennoskäytäntöjä noudattaen.
Skrätsistä tehdyssä sovelluksessa kiehtoi mahdollisuus oppia uutta ja vapaat kädet tehdä parhaalla katsomallaan tavalla. Työn tuottavuus ei mielestämme ollut ongelma, koska jokaiseen tarpeeseen mitä tulisimme keksimään löytyy jonkinlainen avoimen lähdekoodin kirjasto mitä hyödyntää. Toisaalta tuottavuusriski piilee siinä, että kuinka montaa kirjastoa pitää kokeilla ennen kuin löytyy sopiva käsillä olevan ongelman ratkaisemiseksi. Sitten kun saimme tiedon siitä, että lähdetään uudistamaan sivustoa näillä käsillä, niin valinta alustan suhteen olikin jo oikeastaan tehty. Syteen tai saveen, skrätsistä tehdään. Projekti oli käytännössä kiinteähintainen, joten me tekijöinä kantaisimme riskin valintojemme seurauksista.
Lähtökohtamme toteutuksen arkkitehtuuriin oli se, että julkinen sivusto ja työpaikkailmoitusten jättämiseen työnantajien käyttämä ylläpitokäyttöliittymä erotetaan toisistaan kokoaan. Näin muutosten tekeminen yhteen ei olisi turhan riippuvaista toisesta ja päivittäminen sekä jatkokehitys olisi sujuvampaa ja riskittömämpää. Julkinen sivusto tulisi olemaan kasa staattisia tiedostoja (ilman tietokantaa), jotta se olisi mahdollisimman nopea ladata. Julkisen sivuston generointi ja työpaikkailmoitusten julkaisu ja ylläpito tultaisiin rakentamaan Node.js sovelluksina. Tietokannan virkaa toimittaisi MongoDB, jota käytettäisiin JSON rajapinnan kautta. Sovellukset hostattaisiin edelleen Herokussa, josta julkinen sivusto generoitaisiin tietyin väliajoin Amazon S3:een. Tulevaisuudessa mahdollisesti tehtävä työpaikkavahti rakennettaisiin MailChimpin / Mandrilin varaan.
Seuraavassa kuvassa on UX-suunnittelijan näkemys TKrekryn arkkitehtuurista. En tiedä millaisen kuvan kehittäjä piirtäisi.
Backend kehityksestä
Terveyskeskusten ylläpitokäyttöliittymä päätettiin toteuttaa ns. single page JavaScript-sovelluksena, kuten nykyään on muodikasta. Alustava ajatus oli käyttää kehyksenä Ember.js:ää, mutta ensimmäisten kokeilujen jälkeen vaihdettiin Angular.js:ään. Vaihto tehtiin koska todettiin, että Ember.js:ää ei osattu riittävän syvällisesti eikä sitä ehditty projektin puitteissa opiskelemaan. Ennestään tutulla Angularilla saatiin tuottavammin tulosta aikaan. Itse node.js:n päälle tehtävää työsarkaa vähennettiin käyttämällä Express.js kehystä, joka teki MongoDB:tä tietokantana käyttävän REST-palvelun kehittämisestä suoraviivaista ja helppoa. REST-palveluun kirjoitettiin kattavat testit Mocha:n ja Chain avulla ja testipatteria täydennettiin tekemällä vähän end-to-end testejä Protractor:lla. Suurimmat haasteet ylläpitotyökalun toteutuksessa liittyivät IE8:n tukemiseen (josta lisää tuonnempana).
Staattisen sivuston generointiin otettiin avuksi JavaScript:llä kirjoitettu Docpad, jolla noin lyhyesti sanottuna voi generoida kaikenlaisia dokumentteja. Docpad:n laajennukset kirjoitettiin CoffeeScriptillä ja sivupohjat koottiin Jadea hyödyntäen. Docpadissa on paljon hyvää ja valmista, mutta näin jälkikäteen tunteemme sitä kohtaan ovat ristiriitaisia emmekä ole aivan varmoja oliko sen käytöstä enemmän hyötyä vai haittaa. Ensinnäkin työkalussa tuntuu olevan jokin suorituskykyyn liittyvä ongelma, joka johtaa muistin vuotamiseen. Tämän johdosta sovellus pitää välillä uudelleenkäynnistää. Toisekseen Docpadin dokumentaatio jättää toivomisen varaa mm. esimerkkien puuttuessa. Lahjoitimme projektille kuitenkin kokonaiset $7, joten odotukset olivat korkealla 😛
Ideaalimaailmassa heittäisimme Docpadin todennäköisesti roskiin ja tekisimme sivuston generoinnin jotenkin muuten.
Kehitykseen luonnollisesti liittyi keskustelu kehitysympäristöistä jne. ja koska kuulemma Windowsilla ei voi tehdä mitään aikuisten töitä, niin allekirjoittanut käytti projektin ajan “sujuvasti” Nitrous.io kehityspurkkia. Palvelun kautta saa pytyn käytiin muutamalla klikkauksella, mutta se on sitten oma keskustelunsa voiko niillä tehdä oikeasti vakavaa kehitystyötä. Tässä tapauksessa purkki oli minun käyttöön riittävä, mutta johtuen mm. sivuston generoinnin muistinkäytöstä, piti purkista maksaa vähän rahaa. Puolen vuoden aikana palvelu taisi olla kerran pois linjalta ja ihan ymmärrettävästä syystä ks. kuva alla.
Frontend kehityksestä
Kun aloitin kokopäivätyöt alalla 2007, oli Web 2.0 vouhotus käynnissä. Ajax oli myyntisanana keksitty pari vuotta aikaisemmin ja jQuerya oli kehitetty vuoden ajan. IE6 oli valtaselain ja Firefox edusti edelleen kaikkea uutta ja ihanaa. Facebookkiin suhtauduin skeptisesti (Miksi kukaan haluaisi ”mikroblogata” raportoiden arkielämästään julkisesti netissä?!?) ja aikajana näyttää lähinnä kaveripyyntöjä tuolta ajalta ja vähemmälti mitään sisältöä. Työnjako kehittäjän ja käyttöliittymäkaverin välillä oli melko selvä: Kaikki mikä ei ole HTML:ää, CSS:ää ja JavaScriptiä, kuuluu sille backend-tyypille. Eikä sillä JavaScriptillä silloin vielä mitään monimutkaista tehty. Käytetyt softa-alustat (Sharepoint mm.) toivat tullessaan enemmän valmista toiminnallisuutta kuin kukaan ikinä tulisi tarvitsemaan. Käytännössä siis se fronttikehitys minkä minä olen oppinut tuntemaan ja päässäni jäsentämään, oli ensisijaisesti asioiden laittamista näyttämään joltakin ja toissijaisesti niiden laittamista toimimaan jotenkin.
Tuosta ajasta maailma on muuttunut siinä mielessä, että JavaScript on nykyään vakavasti otettava ohjelmointikieli, eikä se enää määritä tapahtuuko kehitys edessä vai takana. Sekä etu- että takapää voidaan toteuttaa JavaScriptillä ja osa sovelluksesta voi olla palvelimella tai sitten se voi toimia kokonaisuudessaan selaimessa. Tämän johdosta front-end kehittäjän toimenkuvan määrittäminen on entistä vaikeampaa. Jos joku toimenkuvallinen raja pitää piirtää, niin mihin se piirretään? Olisiko se esim. HTML, CSS ja JavaScript mVc? Joku voisi kyseenalaistaa, että miksi moinen raja pitää olla olemassa? Eikö kehittäminen ole kehittämistä ja sillä selvä? Tähän vastaan, että tunnen kehittäjiä jotka eivät pitkällä tikullakaan koskisi CSS:ään, jos ei ole aivan pakko ja toisaalta en jättäisi edellä kuvatun arkkitehtuurin suunnittelua itseni harteille. Sitten päästään kysymykseen, että eikö sen graafisen suunnittelijan pitäisi tehdä ne CSS:t, johon vastaan… meistä on moneen veneeseen eivätkä kaikki osaa, ole hyviä tai halua tehdä kaikkea jne. Se on tärkeää, että kaikki projektin jäsenet ovat mukana tekemässä alusta loppuun, mutta siinä ei ole mitään järkeä että kaikki tekevät samoja asioita.
TKrekryssä mentiin tällä linjalla. Minä koostin käyttöliittymät ja Jaakko toteutti niiden toiminnallisuuden. Ylläpitosovelluksessa käyttöliittymä pohjautui Bootstrap CSS-kehykseen, josta oli merkittävä hyöty työn tuottavuudelle, koska näkymät koostuvat pääasiallisesti lomakkeista. Näiden tyylittäminen tyhjästä olisi ollut merkittävä ponnistus suhteessa projektin kokonaisbudjettiin. Yksinkertaisella julkipuolella en katsonut tarpeelliseksi turvautua Bootstrappiin. Projektin alussa oli jo hyvä haju siitä, että CSS:n määrä tulisi olemaan pieni, jolloin myös esiprosessoreiden tuomat tuottavuushyödyt jäisivät pieneksi. Tästä syystä päätin kirjoittaa puhdasta CSS:ää, jota kaiken kaikkiaan syntyi noin 1300 riviä.
Ylläpitosovelluksen toteutuksessa käytettiin Angularia ja muutamaa sen laajennosta mm. tiettyjen käyttöliittymäkomponenttien aikaan saamiseksi. jQueryä ei juuri käytetty muuten, kuin Bootstrapin komponenttien riippuvuuden takia ja senkin riippuvuuden voisi purkaa tulevaisuudessa, jos homma osoittautuu vaivan arvoiseksi.
Mitä tulee tuettaviin selaimiin, niin päätimme kävijätilastojen perusteella tukea vielä IE8:a. Ylläpitopuolella tämä tarkoitti erinäisten kolmansien osapuolien kirjastojen lukitsemista tiettyyn IE8:a tukevaan versioon, erilaisten paikkausten ja tilkkeiden käyttöä esim. respond.js ja kohtuuttomasti revittyjä hiuksia ja bugien perässä juosten hukkaan heitettyä aikaa. Uskon, että IE8 tulee vainoamaan meitä vielä pitkään, koska ainakin ne julkisorganisaatiot joiden kanssa olen ollut tekemisessä, ovat kuolettavan hitaita päivittämään selaimiaan. Kummallista tässä on, se että jos esim. viime syksynä on siirrytty Win XP:stä Win 7:aan, niin oletusselaimeksi on jätetty edelleen IE8 vaikka pari-kolme uudempaakin versiota olisi ollut saatavilla. Tiedä sitten onko vieläkin jossain aikanaan IE6:lle tehtyjä ja ainoastaan quirksmodessa toimivia sovelluksia käytössä, jotka toimivat kehityksen jarruna hankaloittaen selainten päivittämistä uudempiin. En keksi muuta syytä mistä moinen toiminta tai oikeastaan toimimattomuus johtuu. IE8 on nykypäivän IE6, joka olisi syytä toimittaa jo ansaitsemaansa haudan lepoon.
Todettakoon vielä, että valitulla hostausratkaisulla on myös vaikutuksia fronttitekemiseen. Julkinen sivusto on hostattu Amazon S3 ämpärissä ja koska kyseessä ei ole webpalvelin, niin tiedostojen pakkaaminen ja vanhenemisaikojen asettaminen sivuston latausaikojen ja näin ollen käytettävyyden parantamiseksi ei onnistu asetuksia säätämällä. Sivusto pitäisi pakata etukäteen sen generoinnin yhteydessä ja vasta sitten puskea S3:een. S3 käyttää menestyksekkäästi Etageja, mutta tiedostojen vanhenemisaikojen asettaminen sivuston lataamisen yhteydessä vähentäisi palvelimen suuntaan tehtyjä pyyntöjä entisestään. Lisää tekemistä toiveiden tynnyriin. S3:n uudelleenohjauksien rajoituksista kirjoitin edellisessä jutussa.
Avointa lähdekoodia
Sekä julkisen sivuston, että ylläpitosovelluksen lähdekoodit on julkaistu avoimena MIT-lisenssillä ja repot löytyvät GitHubista. Ennen julkaisua kuvatiedostot siivottiin (ja paljon muuta) pois projekteista Cloudinaryyn, koska emme laiskoina jaksaneet lähteä selvittämään mitä niistä olisi lisenssissä pitänyt mainita. Julkisen sivuston projektista löytyy oletettavasti Googlen tekijänoikeuksilla oleva OpenSans fontti(tiedostot), joka on julkaistu Apache 2.0 lisenssillä (jos keksit tästä ristiriidan, niin heitäpä kommentti).
Samoin tällä hetkellä tunnetut bugit ja muutama kehitysehdotus listattiin GitHubiin. Josko ihan vaivihkaa tekisivät itse itsensä. Muuten ei vielä olla hirvittävän avoimessa moodissa, koska esim. ohjeet kehitysympäristön pystyttämiseen puuttuvat. Jos talkoot kiinnostavat, niin kirjoitellaan ohjeita sitten 😉
Retrospektiivi
Kaiken kaikkiaan projekti sujui hyvin ja valmistui budjetissa, aikataulussa ja sisällössä. Seuraavassa kuitenkin muutamia seikkoja joihin kiinnittäisimme seuraavalla kerralla huomiota:
- Joitakin teknologisia oikoteitä on matkan varrella otettu eikä budjettiin mahtunut eri kehityslinjojen saati käytettyjen työkalujen kartoitus ja vertailu riittävällä tasolla. Tämä tulee varmasti kostautumaan jossain vaiheessa ylimääräisenä työnä niin kuin tapana on. Vaikka merkittävää arkkitehtuurisuunnittelua ei voi tai kannata ennen toteutusta tehdä, on epävarmojen asioiden tutkimiselle varattava riittävästi aikaa/pisteitä/tilaa/rahaa budjettiin.
- Jälleen kerran: Työmääräarvio on lähes aina liian pieni. Sen jälkeen, kun arvio asiasta X on annettu, on se syytä kyseenalaistaa iteroimalla asian sisältö uudestaan ja arvaamalla uudestaan.
- Projekti oli liian suuri tehtäväksi siten, kuin se nyt tehtiin eli toinen meistä teki pääsääntöisesti osa-aikaisesti päivällä töitä ja toinen päätoimensa ohella iltaisin. Tämän johdosta ja toisaalta siitä, että meillä ei ollut määräajan kanssa hoppu, projektista tuli kalenteriajassa pitkä. Tämä taas johti esim. siihen, että asioita unohtui enemmän kuin mitä intensiivisemmässä, mutta lyhyemmässä projektissa olisi unohtunut. Toisistaan erillään ja eri aikaan tapahtuva työskentelystä aiheutui myös viestinnällisiä ongelmia, joita ei olisi ilmennyt kasvokkain työskennellessä. Projekti olisi pitänyt jakaa selkeämmin kalenteriin sidottuihin inkrementteihin ja tunnistaa paremmin työt jotka olisi kannattanut järjestää kasvotusten tehtäviksi.
- Alustava backend/arkkitehtuurityö olisi hyvä eriyttää irralleen ominaisuuksista backlogissa. Ehkä, mutta sitten mennään oppikirjojen antia vastaan siitä, että jokaisen asian backlogissa pitää tuottaa näkyvää arvoa asiakkaalle ja loppukäyttäjälle…
Ja lopuksi: Älä tee kiinteähintaisia projekteja PISTE.