GitHubããã³
NPMã©ã€ãã©ãªã
node.jsãšã¯é¢ä¿ã®ãªãæªç¥ã®éçŽã ããããhabrã§ã¯ãåçãæ·»ä»ããã®ãè¯ã圢ãšèããããŠããŸãå°ãåã«ãnode.jsã§* SQLãªã©ã®ãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ãMongoãªã©ã®noSQLã䜿çšããã®ã¯è€éã§ããªãããã°ã©ããŒã®é床ã«åããã代æ¿ãœãªã¥ãŒã·ã§ã³ãäœæããã®ãïŒé床ã«åãããåŸæ¥ã®ãœãªã¥ãŒã·ã§ã³ãšæ¯ã¹ãŠïŒããŒã¿ããŒã¹ãæäœããïŒããã³æå°ãšã³ããªãããå€ã®APIã®åçŽããšã³ã³ãã¯ããã æåã®ã€ã³ã¹ãã¬ãŒã·ã§ã³ã®æºã¯ãã¬ããŒã
ãminimal surface APIã ã2çªç®-ããã«ãã¯ãŒã«ã®æåãª
åŒçšããã°ã©ããŒã¯ãã¢ããªã±ãŒã·ã§ã³ã®éèŠã§ã¯ãªãéšåã®é床ãå¿é
ããç°åžžãªæéãè²»ãããå¹çãé«ãããããã®è©Šã¿ã¯ããããã®ã¢ããªã±ãŒã·ã§ã³ã®ãããã°ãšãµããŒãã«æ·±å»ãªåœ±é¿ãåãŒããŸãã ææå°æ©ã®æé©åã¯ãã¹ãŠã®æªã®æ ¹æºã§ã ã
Dixleimer 1ïŒããã§èª¬æããã©ã€ãã©ãªã¯åæããŒã¿çã§ãã ä»ã®ãšãããããªãã®äººçã®åæ¥çãŸãã¯éèŠãªãããžã§ã¯ãã«ã¯äœ¿çšããªãã§ãã ãããå
責äºé
2ïŒããã¹ãã«ã¯è€éãªçšèªã衚瀺ãããã³ãŒãäŸã«ã¯å€ãã®ES6æ©èœããããŸãã äœããç解ã§ããªããšæãããå Žå-ã³ã¡ã³ããæžããŠãã ãããç§ã¯ããã¹ããç°¡çŽ åããã³ãŒãã«ã³ã¡ã³ããè¿œå ããããšããŸãsequelizeã䜿çšãããšãïŒä»ã®ã©ã€ãã©ãªã®æ¹ãè¯ããšã¯æããªãã§ãã ããïŒãã©ãããŠãããè€éãªã®ããšæããæããŸããã ãããå
éšããã©ã®ããã«æ©èœããããç解ãããšãã芳ç¹ã§ã¯ãªãããã-ç§ã¯ã©ã€ãã©ãªã€ã³ã¿ãŒãã§ãŒã¹ãæãäžããŸãã ããããæã䌞ã³ãªãããéçºè
ãç§ã®ããã§ã¯ãªãDBAã«çŒãä»ããŠãããã®ã©ã¡ããã§ãã
ä»ãç§ã¯åœŒããããŒã«ããã¯ã¹ã«è¿œå ããããšããããšãäœãã§ããããç¥ã£ãŠããŸãã åºåã¯ãåã®14ãçµã¿åããã15çªç®ã®æšæºã§ããå°çã®ãããªãžã£ã°ãªã³ã°ã®çµã¿åããã¯ãMySQLãSQlite3ãPostgresãCouchDBãMongoãRedisãNeo4jãªã©ã®éåžžã«å€æ§ãªããŒã¿ããŒã¹ã®ãªã¹ãã§äœ¿çšã§ããããšã瀺ããŠããŸãã
ããããå°èŠæš¡ãªãããžã§ã¯ã-ããããçš®é¡ã®ãã¬ã°ã©ã ããããéçºãµãŒããŒãããã³SPA-ã®å Žåãè€éãªORMã¢ãããŒãã®è£ã«ããæ©èœã®è€éãªéšåã¯å¿
èŠãããŸããã§ããã åºæ¬çã«å¿
èŠãªæ©èœã¯ãã¬ã³ãŒããæ¡ä»¶ããã³é¢ä¿ã«ããéžæã®ä¿åãšæ€çŽ¢ã§ãã
ææå°æ©ãªæé©åã¯å¿
èŠãããŸãããããŒã¿ããŒã¹ãããã£ãŒã«ãã®äžéšãååŸããããã¯ãšãªã®æé©åãè¡ã£ãããé¢æ°ãä¿åãããããŸãã ãªã¬ãŒã·ã§ã³ã®éžæïŒãªããžã§ã¯ããšãã¹ãŠã®æ¥ç¶ãååŸããïŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ã«ãã£ãŠåœ¢åŒåã§ããŸãã é床ãäœäžããããã宣èšæ§æã®è¿œå ãšã³ãã£ãã£ã®æããªããªããŸãã æãçŽç²ãªåœ¢ã®ãªãã«ã ã®ã«ããœãªã
åæ
çãªäœè«ïŒæ°äžäººããæ°åäžäººã®ãŠãŒã¶ãŒããããããžã§ã¯ãã®éçºã®æŽå²ãèŠããšãäžå®ã®æéãçµéãããšãéçºè
ã¯ã¹ããŒãã倱ããŸãã ã¯ãšãªãããŒã¿ããŒã¹ãèšèªããã©ãããã©ãŒã ãå€æŽããŠæ©èœããããã«ããŸãã ãããžã§ã¯ããæ®åœ±ãããå Žåã圌ã¯éšåã亀æããå¿
èŠããããããŒã¹ã§æåã«äœæ¥ããã®ã¯ãæåã®åªåããå°æ¥ã®ããã«ãè²»ããããŠããªãå Žåã§ãã åæã«ãéããŠè€éãªORMæ§æã¯çœ®æãè€éã«ããŸãã çµè«ã¯æããã§ããORMã®éžæãå°æ¥ã®éæè¡çãªè² åµãšããŠè©äŸ¡ããå Žåãå¹çã®äœããœãªã¥ãŒã·ã§ã³ãéçºè
ã®é床ãæäŸããæå°éã®APIãæäŸããããšãæ£ããéžæã§ãããå¥ã®ãœãªã¥ãŒã·ã§ã³ãžã®ç§»è¡ãç°¡çŽ åããŸãããŠããããäœããŸãã
DBã§ã¯ãªããJSäžå¿ã®ActiveRecord-ãã ããäžéšã®å Žæã§ã¯ãå€å
žçãªãã¿ãŒã³ããé ããããŸããã
ããŒã¿ããŒã¹äžå¿ã§ã¯ãªããããããŒã¿ããŒã¹ã¯ãœãªã¥ãŒã·ã§ã³ã®èŠä»¶ã«åŸã£ãŠéžæããããã®ã§ãããç¹å®ã®ããŒã¿ããŒã¹ã«ã€ããŠæ±ºå®ããããã®ã§ã¯ãªãããšãç解ããããšãéèŠã§ãã Neo4jããªããžããªãšããŠéžæãããŸããã ãã®ãœãªã¥ãŒã·ã§ã³ã«ã¯é·æãšçæããããŸããããããŸã§ã®ãšããããã«å©ç¹ããããŸãã
neo4jã«æ
£ããŠããªãå Žå-ããã¯ãSQLã䜿ããããWebã¯ã©ã€ã¢ã³ããããã¯ã¹ããã®ãã«ããã¹ãã€ã³ããã¯ã¹ïŒluceneã䜿çšïŒãPostgresã«æ¯ã¹ãŠããäœãïŒç·åœ¢ïŒããã©ãŒãã³ã¹ãããåå¿è
ã«ãšã£ãŠã¯ããã«ç解ããããèšèªãåãã人æ°ã®ããã°ã©ãããŒã¿ããŒã¹ã§ã/ Mysqlã ãã¹ãŠã®ã€ã³ã¹ããŒã«æé ã¯ã http ïŒ //neo4j.com/download-thanks/ïŒedition = communityã«ãããŸãã Macã§ã¯ãbrew install neo4jãä»ããŠã€ã³ã¹ããŒã«ãããŸãç°¡åãªæ¥ç¶ãšãšã³ããªããå§ããŸãããã
const {Connection, Record} = require('agregate') const dbPath = 'http://neo4j:password@localhost:7474'; class ConnectedRecord extends Record { static connection = new Connection(dbPath); } class User extends ConnectedRecord {} User.register()
ã³ãŒãã®ããããããããæãåºãå¯äžã®ãã®ã¯ãUser.registerïŒïŒã®åŒã³åºãã§ãã JSã§ã¯ããã³ãã©ãŒããã³ã°ã¢ããããŠã¯ã©ã¹ãäœæããããšã¯ã§ããŸããïŒãããŠããã®ããšã«ã€ããŠèšèªã®éçºè
ã«æè¬ããŸãïŒã
Record.registerã¡ãœããã¯æ¬¡ã®3ã€ã®ããšãè¡ããŸãã
- ãã®ã¯ã©ã¹ãæ¢åã®ããŒã¿ããŒã¹æ¥ç¶ã«ç»é²ããŸãã åã«çœ®ã-æ¥ç¶å
ã®ãããã§ãé¢é£ä»ããã©ãã«ã-ãã¯ã©ã¹ããæšåãããŸãã ïŒåŸã§ãããã«ã€ããŠïŒé¢é£ä»ãã解決ãããšããããŒã¿ããŒã¹ãªããžã§ã¯ããJSãªããžã§ã¯ãã«å€æããããã«äœ¿çšãããã®ã¯ãã®ãããã§ã
- å
éšã©ã€ãã©ãªããã»ã¹ãéå§ããŸãïŒã»ãã¥ãªãã£ã®ããã«ãã€ã³ããã¯ã¹ä»ããšuuidã®äžææ§ã®å¶éïŒ
- ã«ã¹ã¿ã ã€ã³ããã¯ã¹ã®ã€ã³ããã¯ã¹äœæãéå§ããŸãïŒãã®ã¯ã©ã¹ã«èšå®ãããŠããå ŽåïŒã
æœè±¡ã¯ã©ã¹ã®å Žåããã®ã¡ãœãããåŒã³åºãå¿
èŠã¯ãããŸããã
ES2015ã§ã¯ãéçããããã£ã¯ãšã³ãã£ãã£ããããã£ãšåãæ¹æ³ã§ç¶æ¿ãããŸã-瀺ãããŠããããã«ã芪ã¯ã©ã¹ã§äžåºŠconnectonã宣èšãããŸãã ããŒã¿ããŒã¹ã1ã€ãããªãå ŽåãRecord.connectionãæ¥ç¶ã«å²ãåœãŠãããšãã§ããŸãããããã¯éçºã®èŠ³ç¹ããã¯æ£ãããããŸããã
é¢ä¿ãšé¢ä¿
äŸãè€éã«ããŸãããã ACLãå®è¡ããŠããŠãé¢ä¿ãå¿
èŠã ãšæ³åããŠãã ããã
const {Connection, Record, Relation} = require('agregate');
ããèŠãŠããªããšãå®éã«ã¯this.permissionsãå€å¯Ÿå€ã®é¢ä¿ã§ããããšãããã«ããããŸããã ãã®çš®ã®æ§æã䜿çšãããšãæ€çŽ¢ãåé€ãå¯çšæ§ã®ç¢ºèªãªã©ãå®å
šãªã¯ãšãªã䜿çšã§ããé¢ä¿ã®é·ããã§ãŒã³ãæ§ç¯ã§ããŸãã
Relationã¯ãES6ã®çµã¿èŸŒã¿Setãªããžã§ã¯ãããšãã¥ã¬ãŒãããŸãã APIã¯ç°ãªããŸãããããç¥ãããŠãããããã«ç解ãããŸãã éãã¯ãã¡ãœããã¯æ¢ã«ããŒã¿ãè¿ãPromiseãè¿ããsizeïŒïŒã¯ããããã£ã§ã¯ãªãã¡ãœããã§ããããšã§ãã ããã«ãéä¿¡ãããèŠçŽ ã®é
åãšãªã¬ãŒã·ã§ã³ã«å«ãŸããèŠçŽ ã®å
±ééšåãè¿ã#intersectã¡ãœãããšã以äžã®ããã«æããã«ãã#whereã¡ãœããããããŸããã
DBã§æ€çŽ¢
ããã«ã¯ãåãAPIãæã€ã¡ãœããã䜿çšã§ããŸããRecord.whereïŒïŒã¯ã©ã¹ã®ã¡ãœãããšãRelationïŒwhereïŒïŒã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¡ãœããã§ãã 䜿çšå¯èœãªãªãã»ãããå¶éãé åºãå€ã«ããæ€çŽ¢ãé
åã®å
容ãé
åãžã®ãšã³ããªïŒã¯ããåä»ãé
åã¯neo4jã®ããªããã£ãã®1ã€ã§ãïŒããã³ãµãã¹ããªã³ã°ã æ€çŽ¢ã«ã¯å€ãã®æ©äŒããããŸãã ãããã¯ãã¹ãŠã®äž»èŠãªã¿ã¹ã¯ãã«ããŒããŠããŸãã ãã¹ãŠã®ãªãã·ã§ã³ãåæããã®ã¯éåžžã«é£ãããããtypescriptã®ãããªæ§æã§æ£åŒãªèª¬æãèŠãã®ã¯ç°¡åã§ãã
var dbPrimitiveType = bool | string | number | Array<bool> | Array<string> | Array<number> async function where( params?: { [string: queryKey]: dbPrimitiveType | { $gt?: number //greater than - $gte?: number //greater than or equal - $lt?: number //less than - $lte?: number //less than or equal - $exists?: bool // $startsWith?: Array<string> | string // $endsWith?: Array<string> | string // $contains?: Array<string> | string // $has?: Array<dbPrimitiveType> | dbPrimitiveType // $in?: Array<dbPrimitiveType> | dbPrimitiveType // } }, opts?: { order?: string | Array<string>; // - key key DESC key ASC, ['created_at', 'friends DESC'] offset?: number; limit?: number; }, transaction?: Queryable): Array<Record>
ååŒ
äžèšã®APIã䜿çšãããšäœæ¥ã§ããŸãã æ®ã£ãŠããã®ã¯ååæ§ã®åé¡ã ãã§ãããããã¯ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããŠå€å
žçã«è§£æ±ºãããŸãã
éçŽã§ã¯ã2ã€ã®æ¹æ³ã§ãã©ã³ã¶ã¯ã·ã§ã³ãæäœã§ããŸã-åçŽãŸãã¯ç°¡åã§ãã
æ確ãªæ¹æ³ã¯ãé¡ã®ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããããšã§ãã ãããè¡ãã«ã¯ãïŒç¹ã«ïŒæåŸã®åŒæ°ãæž¡ããŸãã ããŒã¿ããŒã¹ã§æ©èœãããã¹ãŠã®æšæºã¡ãœããã¯ããã®è¡šèšæ³ããµããŒãããŠããŸãã
class Post extends Record { author = ::new Relation(this, 'created', {direction: -1}).only
æ¥ç¶ãªããžã§ã¯ãïŒã¯ã©ã¹ãšã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã®äž¡æ¹ã§äœ¿çšå¯èœïŒã¯ãæ¥ç¶ããã©ã³ã¶ã¯ã·ã§ã³ããŸãã¯ãµããã©ã³ã¶ã¯ã·ã§ã³ã§ãã 3ã€ã®ãšã³ãã£ãã£ãã¹ãŠãåãã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããå
éšã®ããããªéããããããã人çã®äœ¿çšã«éãã¯ãããŸããã connection.transactionïŒïŒãåŒã³åºããšãæ¥ç¶ã¯ãã©ã³ã¶ã¯ã·ã§ã³ãè¿ããŸãããã©ã³ã¶ã¯ã·ã§ã³ã¯ãµããã©ã³ã¶ã¯ã·ã§ã³ã§ããããµããã©ã³ã¶ã¯ã·ã§ã³ã¯å¥ã®ãµããã©ã³ã¶ã¯ã·ã§ã³ã§ãã
å
éšã®éãã¯æ¬¡ã®ãšããã§ããæ¥ç¶ã®ã³ãããããã³ããŒã«ããã¯ã¡ãœããã¯ãšã©ãŒãã¹ããŒããŸãããã©ã³ã¶ã¯ã·ã§ã³ãæåŸ
ã©ããã«åäœããå Žåããµããã©ã³ã¶ã¯ã·ã§ã³ã®å Žå-ã³ãããã¯äœããããããŒã«ããã¯ã¯èŠªãã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ããã¯ããŸãã
ããã¯ãããšãã°RecordïŒsaveïŒïŒã®ããã«ãäžéšã®ã¡ãœããããã©ã³ã¶ã¯ã·ã§ã³ãçæããæåŸã«çµäºããããã«è¡ãããŸãã ãã®ãããªã¡ãœããããã©ã³ã¶ã¯ã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯å
ã§æ£ããæ©èœããããã«ããµããã©ã³ã¶ã¯ã·ã§ã³ã®ç¡éã®ãã¹ããå®è£
ãããŠããŸãã
2çªç®ã®æ¹æ³-ã·ã³ãã«-ã§ã¯ããã³ã¬ãŒã¿ã䜿çšãããŸãïŒ
import {Record, acceptsTransaction} from 'agregate' class Post extends Record { @acceptsTransaction async static create(text) { return await new this({text}).save(this.connection) } }
ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
import {Record, acceptsTransaction} from 'agregate' class Post extends Record { async static create(text, transaction) {
äžèšã®äŸã®ããã«ããã³ã¬ãŒã¿ãçŽæ¥äœ¿çšããŠæ§æã§ããŸãã æ§æã®å ŽåãçŸåšäœ¿çšå¯èœãªãã©ã°ã¯1ã€ã ãã§ã-forceã¯ããã©ã³ã¶ã¯ã·ã§ã³ã匷å¶çã«äœæããŸã-ãã©ã³ã¶ã¯ã·ã§ã³ã転éãããªãå ŽåããããäœæããŸãã 次ã®ããã«äœ¿çšããå¿
èŠããããŸãïŒ
@acceptsTransaction({force: true}) ...
泚æããŠãã ãã-çŸåšãthis.connectionã¯ãã©ã³ã¶ã¯ã·ã§ã³ã«ãªã£ãŠããŸãã é¢æ°ãå®äºãããšãããããã£ã¯ä»¥åã®ç¶æ
ã«æ»ããŸããããã©ã³ã¶ã¯ã·ã§ã³ãæž¡ãããšãå¿é
ããã«ã¯ã©ã¹ã®ä»ã®ã¡ãœãããåŒã³åºãããšãã§ããŸãã ãã®éæ³ã¯ããã§ã®ã¿æ©èœããŸãïŒäºæž¬å¯èœã§ãïŒã
ãã©ã³ã¶ã¯ã·ã§ã³ã¯é çªã«åŠçããããããã€ãŸã ãããªããžã§ã¯ããå®äºãããŸã§ãå¥ã®ãªããžã§ã¯ããéå§ããããŸã§ããªããžã§ã¯ãã¯è€è£œãããªãããããã®ãã³ã¬ãŒã¿ã§éçã¡ãœãããã©ãããããšã誀ã£ãŠãã©ã³ã¶ã¯ã·ã§ã³ã倱æããå¯èœæ§ãããããšã«æ³šæããŠãã ããã ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã®å Žåãããã¯ãJSãæ£ããæäœããå Žåããã®ã¹ã³ãŒãå
ã«ãããä»ã®å®è¡ã¹ã¬ããïŒpromiseãasyncãªã©ïŒããåæã«ã¢ã¯ã»ã¹ã§ããªããšããäºå®ã®ãããæãããšã§ã¯ãããŸããããªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ããŸããã
ããããŠãããå
šäœã§ã
APIã®èª¬æãšãAPIããã®æ¹æ³ã§å®è¡ãããçç±ãšãããã§ãªãçç±ã¯å®äºã§ãã
è¿œå ãã䟡å€ã®ããå¯äžã®ããšã¯ãèªåãå人ã®ããã®å°ããªãããžã§ã¯ãã§æ¢ã«äœ¿çšããŠããããšã§ãã é·ãéãããŒã¿ããŒã¹ãæäœãããšãããã®ãããªåã³ãæããŠããŸããã§ãã-Ruby / Railsã§äœæ¥ããŠãããšãã ããäœæ¥ã¡ã«ããºã ã®ãéææ§ããšç解å¯èœæ§ã®æèŠãæããŸããã
ãŠãããã«ã¯æ©èœãé床ãäžè¶³ããŠããå ŽåããããŸããããããå¿
èŠãªå Žåã¯ãããžã§ã¯ãã«æ¥ç¶ããŠãã ããã
éèšã¯ãããªãããçµç¹åãããã³ãŒãã®ããã608è¡ïŒã·ã§ãã¯ïŒã§ãããå€æŽãè¿œå ãæŽæ°ãããã³è¿œå ã®ãã¹ããè¡ãã®ã¯éåžžã«ç°¡åã§ãã 倧èŠæš¡ãªãããã¯ã·ã§ã³ã§ã®äœ¿çšã«ç¹ã«é©ããŠããããšã確èªããããšæããŸãããããããæ°ã«å
¥ã£ãããéçºã«åå ããŠãã ããïŒ