2024. április 18., csütörtök

Gyorskeresés

Egy blog születése Α → Ω

Írta: |

[ ÚJ BEJEGYZÉS ]

Szerettem volna egy blogot csinálni magamnak, eddig az ingyenes megoldásokat használtam, mint blogspot, vagy wordpress, de igazából egyikkel sem voltam megelégedve, illetve szerettem volna gyakorolni valamin. Igy elkezdtem csinálni magamnak egy blogot.

A blognak minden részét magam tervezem implementálni, olyan mélységekben, amennyire csak lehet.

Előkészületek

Először is ki kellett találni a használandó technológiákat. Az ember egy raklap technológia közül választhat, de tényleg. Ha az ember valaki olyant kérdez meg, aki nem követi a trendeket, akkor jó eséllyel azt a tanácsot kapja, hogy PHP + HTML + (Apache, nGinx, IIS stb..). És ez nem vicc, prog.hu-n volt egy hasonló kérdés, ott az emberek 95%-a ezt ajánlotta, mert a PHP jelenleg uralkodó a neten. Ellenben a népszerűsége zuhan, és már vannak jó alternatvák. Én valami újabb technológiát szerettem volna használni, ami sokkal "maibb".

Kliens az egyértelműen JavaScript, de azon belül ezer lehetőség van választani MVC framework-ök, és client-library-k közül. Itt is valami kurrens-et akartam választani.

Végül úgy döntöttem, hogy a backend szerepét a node, a kliens szerepét a Dart fogja betölteni.

Ami kelleni fog: node, npm, yeoman

----- backend -----

A backenddel kezdtem a fejlesztést. Az elképzelés az, hogy a bloghoz szükséges adatok (bejegyzések, kommentek?, felhasználók?) kiszolgálását web szervizek fogják biztositani, amit nodejs-ben valósitok meg. Mivel az egész arra megy ki, hogy gyakoroljak, ezért minden jóval el akarom látni a backendet, és próbálok minél minőségibb kódbázist létrehozni. Emiatt lassan is haladok, hiszen a legtöbb dolog új nekem, mindennek most nézek utána.

Kezdjük el:

Scaffolding: az egész backendnek úgy álltam neki, hogy először is generáltam, egy nálam okosabb/tapasztaltabb emberek által összeállitott sémát Yeoman segtségével, majd ezt tanulmányozva magamtól is összeraktam egy hasonlót, amiben csak azt használom amire szükségem van.

megj: ez csak a példa projekt amit analizáltam

npm install -g generator-node

Csináljunk egy mappát a példa projektnek.

mkdir sampleServer
cd sampleServer
yo node

Ez a parancs egy ilyen projekt struktúrát hoz létre:

.
├── cli.js
├── example
│   └── sampleserver_example.js
├── Gruntfile.js
├── lib
│   └── sampleserver.js
├── node_modules
│   ├── grunt
│   ├── grunt-contrib-jshint
│   ├── grunt-contrib-nodeunit
│   ├── grunt-contrib-watch
│   ├── jshint-stylish
│   ├── load-grunt-tasks
│   └── time-grunt
├── package.json
├── README.md
└── test
└── sampleserver_test.js

Ez lesz a backend alapja.
package.json: Ez az npm init eredményeként létrejövő konfigurációs fájl. Bővebben
Itt azt érdemes megjegyezni, hogy a projekt entry pontja konfigurálva van a fájlban, valamint itt soroljuk fel a projektünk dependenciáit. Ha később bővteni akarjuk a projektet újabb modulok bevonásával, akkor pl:
npm install mocha --save-dev
parancs hatására bővülni fog a devDependencies egy új rekorddal.

Gruntfile.js: a projektünk build eszköze. Bővebben Ebben a fájlban tudunk taskokat definiálni. Olyan ez mint ant esetén a build.xml, csak ebben az esetben ez egy JavaScript fájl. Ebbe most nem fogok bővebben belemenni, majd ha elkészült a blog, akkor ott rok egy, vagy több blog posztot a blog születéséről. Ott ezt is kifejtem. Jelen esetben csak meg kellett értenem a grunt alapvető működését, hogy el tudjam kezdeni vele a munkát. A Gruntfile-ban definiálhatjuk a taskokat, azokat a repetitiv folyamatokat amiket automatizálni szeretnénk. A generátor készitői lintelést és unit tesztelést definiáltak nekünk. Kiindulásnak ez jó lesz.

Ahhoz, hogy kipróbáljuk, hogy hogyan működik a grunt, és, hogy hogyan tudjuk lefuttatni a taskokat, két lehetőségünk van.
Az egyik, hogy lefuttatjuk a grunt parancsot, vagy ami ezzel ekvivalens működést eredményez:
npm run test
Ahol a "test" parancs a package.json fájlban lett definiálva, a "scripts" mezőben. Ez sem csinál mást, csak kiadja a grunt parancsot.

Az eredmény ez lesz:

> sampleserver@0.0.0 test /home/jim/tmp/sampleServer
> grunt

Running "jshint:gruntfile" (jshint) task

✔ No problems


Running "jshint:lib" (jshint) task

✔ No problems


Running "jshint:test" (jshint) task

✔ No problems


Running "nodeunit:files" (nodeunit) task
Testing sampleserver_test.js.OK
>> 1 assertions passed (4ms)

Done, without errors.


Execution Time (2014-07-06 09:43:36 UTC)
loading tasks 389ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 88%
jshint:gruntfile 31ms ▇▇▇▇ 7%
jshint:lib 6ms ▇ 1%
jshint:test 8ms ▇ 2%
nodeunit:files 8ms ▇ 2%
Total 443ms

Mi történt?

hinteltük a a lib mappában lévő *.js fájlokat, a test mappában lévő *_test.js fájlokat, valamint magát a Gruntfile.js-t is. Majd unit teszteltük a test mappában lévő test fájlokat.

Ennyit az információszerzésről, ebből már ki tudtam indulni, de például én nem a nodeunit tesztelőt akartam használni, hanem valami mást. Például jasmine, vagy ami végül bevált, a mocha. Valamint dokumentációt is akartam készteni. Mindenképp olyanra akartam megcsinálni a projektet, hogy az könnyen karbantartható legyen, és minél több olyan eszközt használjon, ami megkönnyti a munkát. Ezért van a grunt, ezért van a dokumentáció, ezért a tesztelések.

woowie

Létrehoztam a blogot tartalmazó projektstruktúrát ami hasonló az előzőhöz, csak kibővtettem:

.
├── bin
├── config
├── doc
├── Gruntfile.js
├── lib
├── package.json
├── README.md
├── test
└── woowieServer.js

Majd a szükséges dependenciákat (hint: ezek bekerülnek automatikusan a package.json-ba)

npm install grunt --save-dev
npm install grunt-jsdoc grunt-contrib-nodeunit grunt-contrib-jshint grunt-contrib-watch load-grunt-tasks time-grunt jshint-stylish grunt-mocha-test should --save-dev

grunt: már lertam, hogy ez mi :)
grunt-jsdoc: ezzel fogunk jsdoc-ot generálni. Bővebben
grunt-contrib-nodeunit: unit tesztekhez. Az én projektemben nem biztos, hogy szerepet kap, de azért nem árt ha van lehetőségünk ilyen teszteket is rni.
grunt-contrib-jshint: jshint
grunt-contrib-watch: figyeli a módostásokat egyes fájlokban, és ha módostás történt, akkor automatikus (újra)futtatja a taskokat.
load-grunt-tasks: utility
time-grunt: utility
grunt-mocha-test: Ezt fogom használni a REST szervizek tesztelésére, valamint az adatbáziskapcsolat tesztelésére is.
should: a tesztekben használom, pl response.should.have.property('statusCode', 200);

REST

Az adatbázis mongoDB, az adatbázis-kliens mongoose, a REST szervizekhez restify-t használtam.

Igy egy REST szerviz definiálása:
woowieServer.js:
function getArticles(req, res, next) {
articleProvider.findAll(req, res, next);
}
server.get('/get/articles', getArticles);

lib/ArticleProvider.js:
ArticleProvider.prototype.findAll = function(req, res, next) {
var articles = this.Article,
promise = articles.find().exec();
promise.addBack(function( err, articles ) {
if( err ) {
console.error("Could not execute findAll query");
}
res.send(articles);
return next();
});
};

A fenti /get/articles szerviz-t implementálás után tesztelni szeretném:

test/woowie_test_mocha.js:
describe('### service: /get/articles', function() {
it('should be up, and running (200 OK)', function( done ) {
client.get('/get/articles', function( err, req, res, obj ) {
assert.ifError(err);
res.should.have.property('statusCode', 200);
done();
});
});

it('should return at least 1 (initial) result', function( done ) {
client.get('/get/articles', function( err, req, res, obj ) {
assert.ifError(err);
obj.should.be.an.instanceOf(Array);
obj.length.should.be.above(0);
done();
});
});
});

Ahol a client, egy tesztelési céllal létrehozott restify JsonClient.

Teszteljük a szervizt: grunt test

Running "mochaTest:test" (mochaTest) task


Testing Database ...
testing basic commands ...
✓ should be able to remove documents
✓ should be able to save new documents (92ms)
✓ should be able to save another one
✓ should be able to create new documents
✓ should be able to count all documents
✓ document count should be equal to three
✓ should be able to remove one document

Testing REST services ...
### service: /get/articles
Woowie Blog Backend listening at http://0.0.0.0:58000
Database Client connected
✓ should be up, and running (200 OK)
✓ should return at least 1 (initial) result
### service: /count/articles
✓ should be up, and running (200 OK)
✓ should return the number of articles
✓ should return an object
✓ should return a >=0 value


13 passing (355ms)


Done, without errors.

Teszteljük élesben:
npm run deploy kimenet
curl http://localhost:58000/get/articles

JSDOC

A generált JSDoc: kép

Összegzés

- van egy nodejs-ben irt http szerverem, ami REST szervizeket definiál, és várja a bejövő kéréseket
- ha jön egy kérés, pl /get/articles, akkor azt delegálja a megfelelő *Providernek, ebben az esetben az articleProvider-nek.
- az articleProvider kapcsolatot létest a mongoDB adatbázissal, és mongoose kliens segtségével lekéri a szükséges adatokat, majd visszaküldi a response-t.
- van egy build tool, grunt, amivel hintelem a fájlokat, jsdoc-ot generálok, és teszteket futtatok
- vegyesen unit teszteket -> nodeunit, rest-teszteket -> mocha, valamint az datbázis alapvető működését is tesztelem -> mocha

----- frontend -----

Működik a backend,irjunk hozzá frontend-et. Kliens oldali tool-nak a Dart-ot fogom használni.
Aki esetleg nem hallott még a Dart projektről, annak álljon itt egy rövidebb/hosszabb ismertető. Ha hallottál már róla, akkor ezt a bekezdést ugord át.

dartlang:

A Dart projekt egy Google által 2011-ben indtott projekt, aminek célja egy új webes programozási platform elkészitése. Az első production-ready relese 2013 novemberében jelent meg, jelenleg az 1.5-ös verziónál tartanak, igy elmondható, hogy elég új dologról van szó. Sokan úgy hirdetik, vagy úgy tudják a Dart-ról, hogy a JavaScriptet hivatott leváltani webes környezetben, de ez nem igaz. Mint ahogy az sem, hogy egy sima compile-to-js toolról lenne szó mint pl a CoffeScript. A Dart ennél sokkal több, és sokkal több is szeretne lenni. Először is rendelkezik egy saját virtuális géppel, ami Dart forrást tud interpretálni. Ez a DartVM, ugye itt már meg is bukott a szimplán c-2-js rumor. Rendelkezik egy dart2js eszközzel ami a Dart forrásból képes effektv JavaScriptet generálni, igy lesz multiplatform a cucc.

Akkor mi is a Dart pontosan?

A dart projekt egy olyan programozási környezet ami rendelkezik egy saját programozási nyelvvel (dartlang) egy saját virtuális géppel (DartVM) egy saját fejlesztőkörnyezettel (Dart Editor) és saját package managerrel (PUB).

A nyelv dinamikusan tipusos, klasszikus öröklődés van benne, nyelvi szinten támogatottak a promisok (Future), kliens és szerver oldalon is használható, és szintaktikában hasonlit a Java-ra.

Bevezetőnek elég ennyi, majd lehet irok a nyelvről egy hosszabb cikket.

Előkészületek

Ami kell: dart (DartEditor + SDK)

Kliens oldali könyvtárak ide nem kellenek, igen rád gondolok jQuery, mivel a nyelv alapból hasonló szintaktikával, és html API-val rendelkezik.

Terv: reszponziv design (Adam Kaplan grid alapján), aszinkron kommunikáció a backenddel (http req + Futures), markdown bejegyzésmegjelentő, AngularDart használata, saját web-komponens a bejegyzéseknek.

A kliens még bőven nincs kész, de már elkezdtem, A következő részben bemutatom a kliens oldali kódot ...

Folytatás ...

Hozzászólások

(#1) Jim-Y


Jim-Y
veterán

Ha esetleg van ötleted, azt szívesen veszem :) Ha hiányoznak a " í "-k akkor az a Chrome-bug miatt van ^^

(#2) Krugszvele


Krugszvele
aktív tag

Én nagyon várom a folytatást.

A tényleg komoly menőségi faktoron, az újdonság varázsán és a mindig újat kell tanulni és azt alkalmazni érzésen kívül milyen tényleges előnyei vannak/lesznek a rendszernek a php+sql-hez képest?
Én tavaly a sajátomat abban írtam és bár ténylegesen egy fapad, csak azok a funkciók vannak benne, amikre nekem igényem van.
Esetleges sebességben, a megnyitáskor van különbség? Gondolom ez csak a közepes és annál bonyolultabbaknál jön elő, mert egy ilyen alap php oldal betöltési ideje is közel nulla.

(#3) Jim-Y válasza Krugszvele (#2) üzenetére


Jim-Y
veterán

Szia.

Szerintem ebben a projektben nem lesz érezhető különbség ilyen téren. Mármint, ez is annyira fapad, és kis volumenű, hogy sebességi különbségekről nincs értelme beszélni.

A node mint kiszolgáló-szerver elméletileg elég gyors tud lenni. A Dart kódból generált JavaScript is nagyon gyors, a V8-as srácok késztik a node2js transpilert, igy a generált kód sebességben megegyezik a kézzel rt JS kódéval. Egyedüli hátránya, hogy a generált js kód az optimalizációnak köszönhetően nagyobb mintha saját magunk iránk. Mondjuk az optimalizációnak hála jobb is :D Minifikálva pedig már elég pici.

milyen tényleges előnyei vannak/lesznek a rendszernek a php+sql-hez képest?

Ezen a kis projekten belül 1 ilyen van, Elég hozzá tudni a JavaScriptet. Az adatbázis mongoDB noSQL adatbázis, dokumentumokat tárolsz benne JSON szerű struktúrában. Amit kiolvasol belőle, azt egyből nyomhatod tovább a kliensnek módostatlanul, és ezt a kliens is baromi egyszerűen tudja kezelni.
Oké, most a kliens pont Dart, ami nem tisztán JavaScript, de ha a kliens mondjuk Angular lenne, akkor meg tudnád osztani a kódot a backend, és a frontend között. És itt most nem arról beszélek, hogy copy+paste-el megosztasz/átmásolsz egy olyan utility function-t amit mindkét oldalon tudsz használni, hanem ennél sokkal direktebb megosztásról, lásd browserify.

Szerintem egy ilyen megoldásnak enterprise környezetben jönnének ki a nagy előnyei:

- a backend, és a frontend is ugyanolyan technológiákkal készülhetne, igy a resource managment könnyebbé válik. Gondolok itt arra, hogy egy olyan developer aki érti a JS-t tud dolgozni a frontenden és a backenden is. Hidd el, ennek van létjogosultsága.

- a projekt jobban átláthatóvá válik

megj: illetve ez már szubjektiv, de a javascript aranykorát éli napjainkban, meg nem mondanánk, hogy már mennyi? talán 19 éve a piacon van, és jól teljesit. Minden hibája ellenére. És még csak most jön az ES6 ami sok olyan dolgot fog javitani benne, ami eddig nehézkes volt. Számomra az egyik ilyen a modul rendszer. Valami 3rd party library (pl RequireJS) segitsége nélkül borzalmas a modularizáció. A Dart ebben például nagyon jó. Ezért is választottam.

[ Szerkesztve ]

További hozzászólások megtekintése...
Copyright © 2000-2024 PROHARDVER Informatikai Kft.