Přejít k navigační liště

Zdroják » JavaScript » IMA.js – setup aplikace a vytvoření modelů

IMA.js – setup aplikace a vytvoření modelů

Články JavaScript

V tomto díle začneme psát naši ukázkovou aplikaci. Povedeme Vás od úplného začátku až po finální deployment do produkce. V průběhu si ukážeme využití všech hlavních vlastností IMA.js a jak vytvořit často používané prvky webových aplikací.

Minule jsme si framework IMA.js představili, dnes se pustíme do práce.

Ukázková aplikace bude zobrazovat počasí v místě, které:

  • uživatel vyhledá pomocí našeho vyhledávání
  • bude zadáno v URL parametru (SEO optimalizace)
  • uživatel nastaví a uloží jej do cookies.
  • je nastaveno v aplikaci jako výchozí, pokud se nepoužije žádná z výše uvedených možností.

Pro jednoduchost pojmenujeme aplikaci WeatherApp.

Devtooly

Než se pustíme do samotného vývoje ukázkové aplikace, rádi bychom zmínili naše vývojové nástroje v podobě rozšíření do prohlížeče Google Chrome, které si můžete stáhnout zde. Tyto nástroje poskytují jednoduchý způsob, jak sledovat a ladit jednotlivá volání a události, které ve vaší aplikaci probíhají.

Vývojovým nástrojům se budeme blíže věnovat v následujících dílech, pokud však chcete, můžete je začít používat už teď. Případně si o jejich možnostech něco pročíst v dokumentaci.

Setup

Slíbili jsme, že to vezmeme od začátku, ale také to nebudeme prodlužovat. Na instalaci taky není nic zajímavého.

K vývoji budete potřebovat:

  • Node.js ve verzi 10 a výše
  • NPM ve verzi 6 a výše.
cd <-- Váš adresář kde máte projekty -->
npx create-ima-app weather-app

Při dotazu na volbu typu projektu vyberte Empty. IMA.js totiž nabízí 3 demo „aplikace“, ze kterých si můžete vybrat. Jejich ukázky najdete na imajs.io/examples.

Pro naši aplikaci postačí základní Empty (Hello world!). Můžete však použít i Todos (TODO list aplikace) nebo Feed (Twitter-like feed aplikace).

Tímto máme vytvořený skeleton aplikace a nainstalované závislosti.

Adresářová struktura

V adresáři naší aplikace vzniklo několik podadresářů: appbuildnode_modules a server. My se budeme zabývat pouze adresářem app (ostatní jsou vysvětleny svým názvem).

  • assets – obsahuje soubory, které jsou zpracovány pre-processory a zkopírovány do build adresáře.
    • less – LESS soubory definující obecná pravidla, makra, mixins a základní strukturu UI.
    • static – jakékoliv soubory, které nepotřebují preprocessing (JS soubory 3. stran, obrázky, …)
  • component – naše React komponenty, které budeme používat ve views. Více o komponentách si řekneme v 3. díle tohoto seriálu.
  • config – konfigurační soubory aplikace. Nyní se konfigurací nebudeme zabývat a ukážeme si jednotlivé možnosti až je budeme potřebovat v průběhu vytváření aplikace.
  • page – controllery, views a LESS soubory k views.
    • error – stránka, která se zobrazí pokud se vyskytne chyba v průběhu aplikace.
    • home – hlavní stránka aplikace
    • notFound – stránka, která se zobrazí pokud uživatel zadá URL na neexistující routu.

Adresáře assets a config jsou povinné a měly by se v aplikaci vždy nacházet. Ostatní jsou volitelné a můžete si je přejmenovat. Je však potřeba upravit některé konfigurace a přihlížet k tomu v následném vývoji aplikace.

Modely

Modely nám v IMA.js aplikacích umožňují pracovat s daty. Pomocí modelů se data načítají, odesílají a transformují. V našem případě budeme využívat základní sestavu modelů (ServiceEntityResource a Factory).

  • Entity představuje objekt držící data nějakého celku (uživatele, článku, …).
  • Factory vytváří ze surových dat instance Entity.
  • Resource stahuje data ze serveru pomocí HTTP požadavků.
  • Service se stará o načítání dat z Resource a následné vytvoření entit pomocí Factory.

Může se vám zdát, že Factory a Resource jsou zbytečné. Data můžeme přece stahovat už v Service a tam také vytváře instance Entity. Ano to jistě můžeme, ale jen v jednodušších případech. Jak se bude aplikace rozrůstat a začnou se objevovat zanořené závislosti, věřte, že samostatné Factory a Resource přijdou vhod.

Pokud by aplikace využívala REST API, můžeme Factory a Resource úplně nahradit použitím @ima/plugin-rest-client. Více o tomto pluginu se dočtete v jeho README.

Na začátku jsme si stanovili, co naše aplikace bude umět. Podle toho si teď rozvrhneme datovou strukturu a vytvoříme modely.

1. Proxy

Data o počasí nám poskytne služba Počasí.cz přes svoje API rozhraní https://wapi.pocasi.seznam.cz. My ale na toto API rozhraní budeme přistupovat přes naši proxy. Vyhneme se tak problémům s CORS.

Proxy vytvoříme na stejném serveru, který se stará o výdej webové aplikace. Ve výchozím stavu je server připravený pouze pro jednu proxy. My jich však budeme potřebovat více. V souboru weather-app/server/server.js – funkce runNodeApp – najdeme řádek:

.use(environment.$Proxy.path + '/', proxy(environment.$Proxy.server, environment.$Proxy.options)

Vidíme, že server používá Express framework a pro proxy jeden z jeho doplňků express-http-proxy. Nastavení proxy se nachází v souboru weather-app/app/environment.js. Soubor obsahuje jednoduchý Node.js modul, který vrací objekt. Hlavními klíči objektu jsou prodtest a dev. Tyto klíče představují nastavení pro jednotlivé vývojové prostředí s tím, že všechny vycházejí z prod prostředí.

Poznámka: Tento styl konfigurace (prod – test – dev) si zapamatujte, neobjevuje se naposledy.

Naši proxy potřebujeme nastavit pouze v produkčním nastavení.

// app/environment.js

module.exports = (() => {
    return {
        prod: {
            // ...
            $Proxy: {
                path: '/api',   // na této URL bude proxy poslouchat
                server: 'https://wapi.pocasi.seznam.cz', // zde bude proxy přeposílat požadavky
                options: {
                    proxyReqPathResolver: function (req) {
                        const queryString = req.url.split('?')[1];

                        return '/v2/forecast' + (queryString ? '?' + queryString : '');
                    }
                }
            }
        }
        // ...
    }

2. Načítání dat o předpovědi počasí

V předchozím bodě jsme si nastavili proxy, která poslouchá na URL /api. Aby jsme URL neopakovali v aplikaci několikrát, přidáme ji do nastavení v souboru weather-app/app/config/settings.js. Zde se používá stejný styl konfigurace jako v environment.js.

// app/config/settings.js

export default (ns, oc, config) => {
  // ...
  return {
    prod: {
        // ...
        App: {
            api: config.$Protocol + '//' + config.$Host + '/api'
        }
    }
  }
}

V adresáři weather-app/app/model vytvoříme podadresář pro předpověď počasí – forecast. V tomto adresáři vytvoříme soubory  ForecastService.jsForecastResource.jsForecastFactory.js a ForecastEntity.js.

Začneme vytvořením ForecastResource. V aplikaci IMA.js funguje DI (Dependency Injection) skrz OC (Object Container). Více o OC a DI se dočtete v dokumentaci.

// app/model/forecast/ForecastResource.js
import { HttpAgent } from '@ima/core';

export default class ForecastResource {
	static get $dependencies() {
		return [HttpAgent, '$Settings.App.api']; // $Settings umožňuje vkládat nastavení pomocí DI
	}

	constructor(http, apiUrl) {
		this._http = http;
		this._api = apiUrl;
    }

    async getForecast(lat, lon) {
		const response = await this._http.get(
            this._api,
            { lat, lon, include: ['place', 'daily'] } // query parametry
        );

		return response.body;
	}
}

Následuje ForecastFactory. Prozatím bude obsahovat jen jednu metodu, která z předaných dat vytvoří instanci ForecastEntity.

// app/model/forecast/ForecastFactory.js
import ForecastEntity from './ForecastEntity';

export default class ForecastFactory {

    static get $dependencies() {
        return [];
    }

    createEntity(data) {
        return new ForecastEntity(data);
    }
}

ForecastEntity pouze vezme data z constructoru a vytvoří si z nich vlastní properties.

// app/model/forecast/ForecastEntity.js
export default class ForecastEntity {

    constructor(data) {
        this.place = data.place;

        this.daily = data.daily;

        Object.freeze(this);
    }
}

ForecastService bude obsahovat prozatím pouze jednu metodu getForecast. Ta pomocí ForecastResource načte data ze serveru a poté vytvoří instance ForecastEntity pomocí ForecastFactory.

// app/model/forecast/ForecastService.js
import ForecastResource from './ForecastResource';
import ForecastFactory from './ForecastFactory';

export default class ForecastService {
    static get $dependencies() {
        return [ForecastResource, ForecastFactory];
    }

    constructor(resource, factory) {
        this._resource = resource;
        this._factory = factory;
    }

    async getForecast(lat, lon) {
        const result = await this._resource.getForecast(lat, lon);

        return this._factory.createEntity(result);
    }

Vytvořili jsme také model pro geocoder – vyhledávání místa podle názvu z URL. Nebudeme zde ale rozepisovat kompletní postup, protože se v mnohém shoduje s modelem pro předpověď počasí. Kompletní podobu geocoder modelu najdete v kódu ukázkové aplikace.

Závěr

Po tomto díle byste měli mít nainstalovanou a funkční IMA.js aplikaci. Zároveň jsme si připravili datovou vrstvu (modely) pro další díl, ve kterém si ukážeme, jak data načítat a zobrazovat.

Komentáře

Odebírat
Upozornit na
guest
2 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře
Antonin Bouchal

Ahoj Vojto.

Býval jsem docela fanda Imy a myslím, že jsme se potkali vašem taky na workshopu o ní.

Nicméně jsem měl za to, že projekt byl mrtvý stejně jako Este. Z jednoduchého důvodu, že vyšel Next.js.

Mohl bys prosím shrnout, v čem nyní spočívá gro a hlavní důvod zvolit imu a ne next.js?

shemale01

jo, v Este jsem dělal, dělal jsem i v Next a musím uznat, že čistý React je lepší, přehlednější. Z mého pohledu ani Ima, ani Next nepřináší nic nového, resp. to co je v nich vyřešeno, není nic co bych nebyl schopen napsat. Nehledě na to, že osobně se mi architektura Nextu nelíbí. Next prošel docela bouřlivým vývojem, dost často se nám stávalo, že nová minor verze rozje**la projekt, přestal fungovat. Za sebe, Next povařuji za paskvil pro lidi, který jsou líní napsat pár řádek navíc. Jo Ima, kdyby vznikla, tak před 10 lety, ale teď je krapet zastarale, hlavně že se snaží do JS zavádět OOP a DI, které sem nepatří. Holt seznam…

Přístupnost není jen o splnění norem: nový pohled na inkluzivní design

Přístupnost a inkluze možná nepatří mezi nejžhavější témata digitálního světa – dokud o nich nezačne mluvit Vitaly Friedman. Na WebExpo 2024 předvedl, že inkluzivní design není jen o splněných checkboxech, ale hlavně o lidech. S energií sobě vlastní obrátil zažité přístupy naruby a ukázal, že skutečně přístupný web je nejen možný, ale i nezbytný.

Efektivnější vývoj UI nebo API: Co si odnést z WebExpo 2025?

Různé
Komentáře: 0
Jak snadno implementovat moderní uživatelské rozhraní? Které funkce brzdí rychlost vašeho webu? A kdy raději sami přibrzdit, abychom využitím AI nepřekročili etické principy? Debatu aktuálních dev témat rozdmýchá sedmnáctý ročník technologické konference WebExpo, která proběhne v Praze od 28. do 30. května. Který talk či workshop si rozhodně nenechat ujít? Toto je náš redakční výběr z vývojářských hroznů.

Zapřáhněte AI jako nikdy předtím. Květnová konference WebExpo přivítá hvězdy technologického světa

Od 28. do 30. května 2025 promění pražský Palác Lucerna na tři dny technologická konference WebExpo. Na programu je více než 80 přednášek a workshopů od expertů z celého světa. WebExpo tradičně propojuje vývojáře, designéry, marketéry i byznysové lídry a nabízí praktické dovednosti, strategické myšlení a přináší nejnovější trendy nejen v oblasti AI.