Meteor

Vi har igennem længere tid ønsket nogle bedre værktøjer til vores administration - registrering af tidsforbrug på vores forskellige projekter, oplysninger om hostingaftaler og den slags. Hidtil har vi brugt nogle små Podio apps som egentlig har fungeret udmærket, men det har været vanskeligt at få et overblik på tværs af de forskellige apps, og det er besværligt at tage sin egen backup af data i Podio. (Podio har passet godt på vores ting hidtil, men alligevel).

Vi er endt med at lave vores egen løsning i Meteor, et framework baseret på JavaScript og Node.js. Meteor har vist sig at være let og hurtigt at arbejde med, og det har været (relativt) enkelt at sætte vores nye administrationssystem i produktion. Vi er glade for resultatet - systemet er hurtigt, vi kan se hinandens opdateringer med det samme, uden at vi behøver trykke på browserens "refresh" knap hele tiden.

Det er vores første Meteor-projekt, og andre kan måske have glæde af et kort resumé over nogle af de overvejelser vi har været igennem undervejs:

Database

Meteor er tæt integreret med MongoDB som er en dokument-orienteret database. Egentlig ville en relationsdatabase være bedre egnet til vores applikation, men vi vurderede at det ekstra arbejde med at bruge MariaDB eller lignende i stedet for MongodDB ville være så stort at det ikke ville være realistisk at give os i kast med. (Selv om der er gode argumenter for at det kan være et farligt kompromis)

Meteor Packages

Meteor giver mulighed for at udvikle moduler med færdig funktionalitet som andre udviklere så kan downloade og bruge (typisk via Atmosphere). Der er rigtig mange Meteor packages til download, og man kan spare rigtig meget tid vil at tage udgangspunkt i andres arbejde i stedet for selv at genopfinde den dybe tallerken.

Der er ingen kvalitetskontrol af packages der bliver uploadet til Atmosphere, så inden man bruger andres kode i sit eget projekt er det en god idé at lave lidt research. Man kan f.eks. tjekke på GitHub hvor mange personer der har været involveret i udvikling af en pakke, hvad de ellers har lavet, hvor længe projektet har eksisteret, hvor ofte der kommer nye releases, hvilke issues der findes osv. Her er nogle af dem som vi har valgt at bruge:

Bootstrap

Vi bruger Foundation i vores PHP-projekter, men det er op ad bakke hvis man vil bruge Foundation i Meteor, som er helt domineret af Bootstrap. Så vi kastede håndklædet og installerede twbs:bootstrap.

Denne pakke understøtter kun "ren" css, ikke sass eller less. Vi vil helst arbejde med sass, så en af de opgaver vi skal i gang med a.s.a.p. er at se om vi kan få en sass-udgave af Bootstrap til at fungere med Meteor.

Router

Routeren er den komponent der etablerer koblingen mellem URL'er og den HTML der skal sendes til browseren. Vi bruger iron:router som ser ud til at være langt den mest brugte.

Vores applikation har ikke specielt mange URL'er, og iron:router har fungeret fint til formålet.

Datastruktur

MongoDB gemmer data i collections der på overfladen minder om tabeller i en relationsdatabase. Men hvor tabeller er opdelt i kolonner med foruddefineret indhold, så har collections ingen struktur overhovedet.

De data som vi arbejder med er i høj grad strukturerede, og vi vil gerne sikre at den struktur bevares - f.eks. vil vi gerne kunne validere nye data som lægges ind i databasen. Til dette formål bruger vi aldeed:simple-schema og aldeed:collection2 som tilsammen gør det muligt at beskrive strukturen af data i form af et skema som så knyttes til en collection. Herefter valideres alle insert og update operationer mod skemaet inden de gennemføres.

Begge disse packages har fungeret upåklageligt hidtil.

Tabeller

De fleste af de data som vi bruger i denne app vises bedst i tabeller. Vi har brugt aslagle:reactive-table til at vise vores data, i stedet for selv at lave tabellerne i HTML og skrive al den funktionalitet der skal til for at håndtere filtre, paging og sortering pr. kolonne.

Den største begrænsning vi har fundet i denne pakke er at små bogstaver sorteres efter store (så "a" kommer efter "Z") og at danske tegn og sammensatte tegn som "aa" ikke sorteres korrekt. Vi kan leve med det til internt brug, men det ville næppe være acceptabelt i en tilsvarende app udviklet til en kunde.

HTML Formularer

Oprettelse af nyt indhold og redigering foregår i formularer som vi typisk åbner i et modal vindue. Vi har forsøgt os med aldeed:autoform som integrerer med simple-schema og collection2, men det har ikke været nogen success, blandt andet fordi vi ikke har kunnet finde en løsning så vi kan bruge datofelter med en datepicker der arbejder med danske datoformater.

Vi kan ikke leve med at "04/05/2015" er "5. april 2015", og vi vil ikke undvære en datepicker, så autoform ryger ud igen. I stedet laver vi formularerne i HTML og koder selv den funktionalitet der skal til for at validere input og vise evt. fejlmeddelelser.

Deployment og drift

Det er muligt at købe Meteor hosting som en service, så man ikke selv behøver tage sig af server-relaterede driftsopgaver (se f.eks. Modulus). Vi foretrækker selv at bevare kontrol over driften, så vi har valgt at bruge Meteor Up til deployment på vores egen VPS.

Meter Up (eller "mup") installerer pr. default MongoDB på samme VPS som app'en kører på, men vi foretrækker at køre databasen på et replica set der er spredt over flere VPS'er (som selvfølgelig ikke skal ligge på den samme server-hardware). Så i vores tilfælde har vi konfigureret mup til ikke at installere MongoDB.

Vores erfaring med drift af MongoDB er lidt begrænsede, så vi kiggede på to forskellige hostede løsninger. Vi begyndte med tre Linode VPS'er og brugte så MMS til at konfigurere og vedligeholde et MongoDB replica set på VPS'erne. Efterfølgende skiftede vi så til en fuldt hostet database med compose.io, mest for reducere driftsopgaverne så meget som muligt. Med de datamængder der er tale om i vores app er compose.io også lidt billigere end en MMS-løsning.

Med MMS kan man fuldstændig selv bestemme hvor i verden databasen er placeret, mens compose.io er begrænset til bestemte datacentre - vi valgte at lægge vores hos DigitalOcean i London. Selve app'en er placeret på en anden VPS i det samme datacenter.

Vi har hidtil foretrukket Linode til drift og kun brugt DigitalOcean til mindre kritiske opgaver. Over det seneste års tid har vi imidlertid ikke oplevet nogen nævneværdig forskel i stabilitet mellem de to, og da vores app fint kan køre på den mindste DigitalOcean droplet har vi placeret den hos dem, for at være så tæt på databasen som muligt.

(Vi har en anden VPS som kører andre Node.js apps (denne blog, f.eks). Vi overvejede at lægge vores nye Meteor app på den samme VPS, men selv med den høje dollarkurs pt. er de $5/måned som vi betaler for en DigitalOcean droplet så lidt at vi ikke syntes det var besværet værd at forsøge at bruge mup med vores eksisterende VPS.)

Videre udvikling

Der er sket meget med Meteor siden vi sidst kiggede på det for et års tid siden, og det har været et meget tilfredsstillende udviklingsforløb vi har været igennem med denne app - vi har en god fornemmelse af at det vi har lavet er robust, og at vi kan holdet det i drift uden alt for meget besvær og med et fornuftigt omkostningsniveau.

Vi startede projektet med en ambition om at bruge test-drevet udvikling, men efter at have bøvlet et par dage med med Velocity og Jasmine uden rigtig at komme nogen vegne gav vi op. Vi vender tilbage til tests når vi har fået lidt mere erfaring med Meteor (og helst inden vores app vokser sig så stor at vi ikke længere kan klare os uden automatiske tests).

Ellers er næste opgave at lave en app der giver vores brugere mulighed for at se og rette egne oplysninger i vores system. Enten i form af en web-app eller en mobil-app baseret på cordova som Meteor har support for.