Úvod do webové platformy Meteor

Co to je a k čemu to je?

Vítejte na webu krátkého neoficiálního tutoriálu k platformě Meteor, ve kterém si zkusíme vytvořit jednoduchou chatovací aplikaci. Meteor je platforma, jejíž hlavní předností je jednoduchá synchronizace dat mezi serverem a klientem a používání klientské predikce. Komunikace mezi klientem a serverem vůbec funguje trochu jinak, než na co jsme u webových stránek zvyklí. Meteor totiž nepoužívá klasický webový model, kdy jsou informace rozděleny do stránek a klient a server si pomocí protokolu HTTP vyměnují požadavky na navigaci mezi stránkami. V případě Meteoru se protokol HTTP použije pouze k získání jedné stránky, která aplikaci představuje, a veškerá další komunikace probíhá pomocí protokolu WebSocket nad TCP, což bývá tradičně spíše doména desktopových aplikací. Tyto vlastnosti společně zajišťují, že aplikace na platformě Meteor reagují na uživatelský vstup okamžitě a jsou tedy vhodné pro interaktivní aplikace jako třeba náš chat.
V našem tutoriálu předpokládáme základní znalosti HTML a JavaScriptu, tutoriál je doplněn obrázky ilustrujícími žádoucí vzhled aplikace v daném kroku a fragmenty kódu, které k tomuto stavu vedly. Tutoriál je koncipován jako jednodušší varianta oficiálního tutoriálu na domovských stránkách platformy Meteor. Ale teď už se do toho pusťme!

Příprava prostředí

Před tím než začneme, je potřeba Meteor nainstalovat. V systémech Windows stačí stáhnout oficiální instalátor a spustit ho. Po úspěšné instalaci se Meteor zeptá na uživatelské jméno a heslo pro Meteor účet. Pokud jsme již používali Meteor, můžeme vyplnit naše existující informace, v opačném případě přímo v okně pohodlně účet vytvoříme. Pozor, pro dokončení instalace je potřeba restartovat Windows. V systémech OS X a Linux se Meteor instaluje pomocí příkazové řádky, v tomto tutoriálu ale budeme předpokládat spouštění na Windows. Bližší informace k instalaci na jiných systémech najdete na oficiálních stránkách.
Po instalaci už můžeme vytvořit náš první projekt v Meteoru! Toho docílíme tak, že si vybereme libovolnou složku a pustíme v ní příkazový řádek (například napsáním cmd do adresního řádku prohlížeče souborů), do kterého zadáme příkaz meteor create chat. Všimneme si, že se nám vytvořila složka jménem chat a v ní tři soubory:
Kromě nich se tam nachází také složka .meteor, se kterou ale nebudeme chtít nijak manipulovat, neboť obsahuje nastavení Meteoru samotného. Když nyní přejdeme do složky s projektem v příkazové řádce (cd chat), můžeme pustit aplikaci pomocí příkazu meteor. Když pak přejdeme v prohlížeči na adresu http://localhost:3000/, můžeme naši novou aplikaci začít používat!

Zobrazování pomocí šablon

Naše aplikace je pěkná, ale chat popravdě zatím příliš nepřipomíná. To se nyní pokusíme napravit a přidat základní zobrazování zpráv. Nejprve musíme nějaké zprávy mít, pro jednoduchost začneme statickými daty. Datový zdroj do Meteoru přidáme tak, že obsah chat.js nahradíme následujícím fragmentem:

if (Meteor.isClient) { 

  Template.body.helpers({
      messages: [       
      { sender: "Karen", text: "Hey guys :)" },      
      { sender: "Foggy", text: "Hello sir!" },
      { sender: "Matt", text: "Hi Foggy!" }
      ]    
  });  
  
}
      
V tomto fragmentu nejprve otestujeme, jestli běžíme na klientovi (tedy v prohlížeči). To proto, že obsah našeho chat.js souboru se v Meteoru pouští jak na klientu, jak je u JavaScriptového kódu zvykem, tak na serveru. Nás v tuto chvíli zajímá část pro klienta, vytvoříme si tedy pomocnou položku messages, ke které můžeme přistupovat kdekoliv v tagu body. V ní budeme od této chvíle uchovávat zprávy. Nyní zbývá ještě zprávy nějak zobrazit. Nahradíme obsah chat.html následujícím fragmentem:

<head>
  <title>My own chat</title>
</head>

<body>
  <div id="main">
    <h1>My own chat</h1>
    <div id="msgContainer">
      {{#each messages}} {{>message}} {{/each}}
    </div>
  </div>
</body>

<template name="message">
  <div class="message">
    <span class="sender">{{sender}}:</span>
    <span>{{text}}</span>
  </div>
</template> 

Kromě standardního html se tu objevuje několik zajímavých věcí. První z nich je Meteor příkaz {{#each messages}}, který způsobí průchod našimi zprávami, které jsme definovali v předchozím kroku. Uvnitř příkazu se používá níže definovaná šablona message, pomocí zápisu {{> message}}. Význam je takový, že každý prvek zobrazíme pomocí šablony, tedy ho převedeme na nějaký kus html kódu. To, o jaký kus kódu se jedná, určuje definice šablony pomocí speciálního tagu template, všimneme si, že se v ní kromě html na které prvek převádíme objevují i výrazy typu {{sender}} a {{text}}. Ty představují mapování na data, a pro každou zprávu se v šabloně nahradí odpovídající hodnotou.
Podíváme-li se nyní na aplikaci v prohlížeci, uvidíme již seznam našich zpráv (s nejnovější zprávou co nejvíc nahoře). Abychom vytvářeli trochu hezčí chat, můžeme použít připravený vzhled. Můžeme si všimnout ještě jedné věci - jakmile jsme provedli změny kódu, propagovaly se do prohlížeče. Protože Meteor aplikace udržuje aktivní spojení se serverem, a server sleduje změny na svých souborech, může na změny zareagovat přenesením nového kódu aplikace.

Ukládání dat pomocí kolekcí

Teď bychom měli být ve stavu, kdy se nám rozumně zobrazují tři přednastavené zprávy. Pro potřeby chatu bychom ale rádi měli k dispozici perzistentní databázi, do které bychom si zprávy ukládali. Meteor podporuje přímo perzistentní úložiště pomocí takzvaných kolekcí, do kterých můžeme ukládat libovolné objekty. Potřebujeme si tedy vytvořit kolekci pro zprávy. Toho docílíme následujícím kódem v chat.js:

Messages = new Mongo.Collection("messages");

if (Meteor.isClient) { 

  Template.body.helpers({
      messages: function () {
        return Messages.find({}, {limit: 12, sort: {createdAt:-1}});
    } 
  });
}    
      
Nejprve vytvoříme proměnnou pro kolekci se jménem messages. Všimneme si, že to děláme mimo blok představující logiku klienta. To proto, že kolekci potřebujeme mít přístupnout na serveru i klientovi. API pro vytváření kolekce je symetrické, i když představuje něco trochu jiného - na serveru se nám skutečně vytvoří (nebo otevře) datová struktura obsahující naše data, zatímco na klientovi se vytvoří jakási cache, kterou Meteor slibuje synchronizovat s kolekcí na serveru. Kromě toho akorát musíme místo statických dat poskytovat data pomocí volání funkce find, která má dva parametry. Prvním je takzvaný selektor, jenž umožňuje vyhledávat konkrétní data, ten v našem případě necháme prázdný (neboť chceme všechny zprávy). Druhým parametrem je objekt specifikující nastavení vyhledávání. V našem případě nastavíme položky limit (počet zpráv, které chceme zobrazit) a sort. Sort říká,j ak položky třídit, my použijeme datum vytvoření v inverzním pořadí - toho docílíme pomocí hodnoty -1, vzestupné seřazení by mělo hodnotu 1. Když se podíváme na stránku, zjistíme, že nám zmizely zprávy! To je proto, že kolekce je zatím prázdná. Meteor nám pomocí příkazu meteor mongo umožňuje přímo manipulovat s databází, ve které se uchovávají kolekce, my se ale pustíme rovnou do přidávání dat (v našem případě posílání zpráv) z webové aplikace.

Vkládání dat

Abychom zprovoznili posílání zpráv, musíme jednak přidat formulář, přes který budeme zprávy odesílat, ale hlavně také zajistit ukládání takto odeslaných zpráv do naší kolekce. Začneme formulářem a do chat.html vložíme mezi nadpis a zprávy tento fragment html:

<form id="msgInput">
  Nickname: <input name="sender" id="sender" type="text" />
  <input name="messageText" id="messageText" type="text" placeholder="Type your message..." />
  <input name="submit" id="submit" type="submit" value="Send message" />
</form>

Tím by se nám měl v prohlížeči zobrazit formulář pro odesílání zpráv. Zbývá mu přidat funkcionalitu. Toho docílíme tak, že do chat.js přidáme pod registraci helper položek i registraci reakcí na události, aby celý soubor vypadal takto:

Messages = new Mongo.Collection("messages");

if (Meteor.isClient) { 

  Template.body.helpers({
      messages: function () {
        return Messages.find({}, {limit: 12, sort: {createdAt:-1}});
    } 
  });
  
  Template.body.events({

    "submit #msgInput": function (event) {
      // Zrušíme implicitní HTTP submit
      event.preventDefault();
        
      // Získáme odesílatele a text zprávy 
      var text = event.target.messageText.value;
      var sender = event.target.sender.value;
  
      // Uložíme zprávu do kolekce
      Messages.insert({
        sender: sender,
        text: text,
        createdAt: new Date()
      });
  
      // Smažeme text zprávy ve formuláři
      event.target.messageText.value = "";
    }    
  });   
}
    
Podíváme se, co se tu vlastně děje. Události v Meteoru jsou dvojice popisu události a reakce. Popis je řetězec, jenž sestává ze jména události (v našem případě submit, tedy odeslání formuláře) a CSS selektoru identifikují prvek, na kterém na událost čekáme. Reakcí je funkce s parametrem event, jejíž tělo se provede když událost nastane. V něm přerušíme odesílání formuláře, získáme z něj data a uložíme je do naší připravené kolekce Messages. A to je vše! Když teď otevřeme aplikaci, uvidíme, že už můžeme zprávy posílat a odeslané zprávy se nám správně zobrazí v aplikaci. Ale nejen to. Když si otevřeme dvě okna s aplikaci, zjistíme, že se nám zprávy bez námahy a okamžitě synchronizují!

Deployment

Teď když máme chat, nebylo by špatné, kdyby do něj mohli psát i ostatní. V současnosti nám Meteor běží jen lokálně na našem počítači, Meteor ale obsahuje i jednoduchý deployment na oficiální hosting. Toho docílíme pomocí příkazu meteor deploy jménoaplikace.meteor.com. Meteor bude chvíli uploadovat data naší aplikace, ale až se mu to podaří, bude naše aplikace volně přístupná na adrese http://jménoaplikace.meteor.com. Nyní již můžeme přizvat pár kamarádů a chatovat online!

Pár poznámek na závěr

V tomto krátkém tutoriálu jsme se dotkli povrchu platformy Meteor a postavili si pomocí pár řádků kódu funkční interaktivní chat (který by samozřejmě stálo za to ještě notně vylepšit). Naučili jsme se pracovat se šablonami, zobrazovat kolekce a vkládat do nich obsah. Některé zajímavé aspekty Meteoru jsme ale stále neviděli. Předně, nevyzkoušeli jsme si jak se z kolekcí data mažou a jak se mění, neboť to pro chatovací aplikaci není extrémně smysluplná funkcionalita; použití je nicméně podobné vkládání. Další věc co stojí za zmínku je, že Meteor obsahuje funkcionalitu pro práci s uživatelskými účty a přihlašováním - pokud bychom chtěli tedy do chatu takovou funkcionalitu dodat, stačí použít tyto vestavěnné účty. A poslední bomba na úplný závěr - Meteor aplikace se dají pomocí několika příkazů deployovat i jako mobilní aplikace pro Android a iOS!