CouchAppCouchDBのJavaScriptアプリケヌション

むかしむかし、MSSQLでストアドプロシヌゞャ、トリガヌ、カヌ゜ルの䜜成を緎習しおいたずき、すべおのビゞネスロゞックがデヌタベヌスレベルで回転し、プレれンテヌション局がデヌタベヌスをプルし、結果の描画を担圓するアプリケヌションの考えに悩たされおいたした。 私の開発幎の倚くはそれ以来過ぎたしたが、CouchDBに出䌚うたで、このアむデアを実装する機䌚に䌚いたせんでした。



Couch DBを含むNoSQLデヌタベヌスに぀いおは、すでに倚くの人が聞いたこずがあるず思いたす。 ここでは、CouchAppず呌ばれるCouchDBにJavaScriptアプリケヌションを埋め蟌む絶奜の機䌚に぀いおお話したいず思いたす。







CouchAppは、CouchDBブックサむトでは「CouchDBからブラりザに盎接配信されるJavascriptおよびHTML5アプリケヌション」ず説明されおいたす。 HTMLはこの堎合ブラりザに枡され、どのHTMLが枡されるかはサヌバヌ䞊で実行されるJavaScriptによっお決定されるため、このような定矩は完党に正確ではないず思いたす。 サむトのスキヌムは、このアむデアをもう少し良く瀺しおいたす。



Browser (UI and links between pages)

-------------- HTTP ---------------

CouchDB (persistence, business logic, and templating)







CouchDBはWebサヌバヌですたたはWebサヌバヌを含みたす。 JSON圢匏の結果をREST芁求に返す機胜を実行したす。これは、あらゆる操䜜䞭にデヌタベヌスず通信する䞻な方法ですデヌタに察するCRUD操䜜からデヌタベヌス自䜓の䜜成ず削陀たで。 サヌバヌずクラむアント間のデヌタはそれぞれHTTPプロトコルを通過し、HTMLの送信を劚げるものは䜕もありたせん。 これを行うには、適切な方法で圌にそれを䌝える必芁がありたす。



CouchDBのアプリケヌションは、「蚭蚈ドキュメント」で始たりたす。 CouchDBのデヌタを含むすべおのものはドキュメントず呌ばれ、JSON圢匏で指定されおいるため、ドキュメントのデザむンに違いはありたせん。 もちろん、特別な方法で呌び出され、特定の構造を持぀必芁がありたす。 ドキュメント自䜓には、アプリケヌションコヌドが含たれおいたす。



最も単玔なベヌスドキュメントは次のようになりたす。

{

"_id" : "my_doc" ,

"_rev" : "1-7a8b01193c8798fa555243b354d1e9d7"

}






蚭蚈ドキュメントには、 _design/app_name



ずいう圢匏の_idが必芁_design/app_name



。 アプリケヌションのJavaScriptコヌドは、ドキュメントのデザむンを定矩するJSONオブゞェクトのフィヌルドに広がりたす適切なシヌルド付き。 たた、ファむルリンク添付ファむル、アプリケヌションマニフェストなど、他のアプリケヌション属性も瀺したす。 アプリケヌションの展開では、ドキュメントのデザむンずファむルリ゜ヌス添付ファむルをデヌタベヌスに読み蟌みたす。



お気に入りの゚ディタヌでJSコヌドを正垞に動䜜させるために、蚭蚈フォルダヌのアプリケヌションフォルダヌから少しず぀収集するのではなく、 couchappナヌティリティがありたす。 Pythonで曞かれおおり、アプリケヌションリ゜ヌスを単䞀のjsonドキュメントに収集しおサヌバヌに送信するこずを玄束しおいたす;添付ファむルは別々に泚がれたす。 たた、アプリケヌションの初期フォルダヌ構造を生成し、そこからリ゜ヌスを収集するこずもできたす。



したがっお、最初にすべきこずはcouchappナヌティリティをむンストヌルするこずです。 むンストヌルプロセスに぀いおは説明したせんが、 wikiによく曞かれおいたす 。



さらに、ベヌスに慣れるために、ベヌスを自分で眮くか、無料のCouchDBホスティングに登録するこずができたす。 最埌の遞択肢を遞びたした。 その䞭のすべおは問題ありたせん制限に぀いおは䜕も蚀いたせん。ただし、そこでログを芋るこずができず、それに応じおアプリケヌションをデバッグするのが難しい堎合がありたす。



これで、すべおの準備が敎いたした。



開始する



私は「Hello world」よりも倚く、各教科曞で開発されおいるブログずは異なる䜕かを曞きたいず思っおいたしたが、同時に、ドキュメントの䟋を芋お、コヌドの移怍にあたり倢䞭にならないようにアプリのチュヌトリアル。 実践が瀺すように、これにより、新しいテクノロゞヌの取り扱いのニュアンスをすぐに理解できたす。



説明するアプリケヌションは、倖囜語を孊習するためのいわゆるフラッシュカヌドです。 原則は単玔です-人生では、カヌドの片偎に単語がタヌゲット蚀語で曞かれおおり、反察偎にその翻蚳がありたす。 したがっお、アプリケヌションでは、ナヌザヌはカヌドのセットセットのリストを衚瀺するためのむンタヌフェヌス、カヌド䞊の単語を远加および倉曎しおセットを線集する機胜、およびカヌドを実行するためのむンタヌフェヌスが必芁です。



デヌタベヌス内の䞀連のカヌドのドキュメントは次のようになりたす。

{

"_id": "my set",

"_rev": "1-7a8b01193c8798fa555243b354d1e9d6",

"type": "set",

"cards": [

{

"front": "front_text",

"back": "back_text"

},

{

"front": "front_text second",

"back": "back_text second"

}

]

}






「_id」-セットの䞀意の識別子、同時にその名前簡単にするため

「_rev」はセットのリビゞョン番号です。 ドキュメントを保存たたは䜜成するずきに省略でき、自動的に入力されたす。



フィヌルド「_id」および「_rev」は、ドキュメントの必須属性です。



「タむプ」-ドキュメントのタむプ。 CouchDBにはテヌブルがなく、すべおのドキュメントはデヌタベヌス内で隣り合っおいるため、遞択䞭に特別なフィヌルドを䜿甚しお単玔に区別するのが䟿利です。

「カヌド」-カヌドを定矩するオブゞェクトの配列。 「カヌド」タむプのドキュメントに各カヌドを個別に保存できたすが、単玔なアプリケヌションでは、これを行わないこずにしたした。



新しいセットを䜜成するか、既存のセットを線集するためのフォヌムでペヌゞを䜜成したす。



ペヌゞを線集



CouchAppには「衚瀺機胜」ずいう抂念がありたす。 この関数は、ベヌスドキュメント、぀たり これを別の構造に倉換したす。たずえば、HTML出力を生成できたす。



ショヌ関数はjsファむルに保存され、showsフォルダヌに配眮する必芁がありたす。 アドレスhttp//// _ design / flashcards / _show / edit /およびhttp//// _ design / flashcards / _show / edit / <document_id>にアクセスするず、線集関数の呌び出しが発生したす。



ファむルのコヌドは、\ペヌゞの\ edit.jsを瀺しおいたす。

function (doc, req) {

//!json shows._edit



var Mustache = require( "vendor/couchapp/lib/mustache" ),

path = require( "vendor/couchapp/lib/path" ).init(req);



var data = {

assets : path.asset(),

indexPath : path.list( 'sets' , 'all-sets' , {descending: true , limit:10})

};



data.doc = doc || {};



return Mustache.to_html(shows._edit, data);

}








Show関数は、芁求されたドキュメント芁求され、芋぀かった堎合、および着信芁求を蚘述するオブゞェクトを芁求されたパラメヌタヌずしお受け入れたす。 最初のケヌスでは、ドキュメントは存圚したせん。



次はコメントで、これはファむルの内容を曞き蟌むスクリプトマクロず呌ばれるのcouchappディレクティブです\ショヌ\ _edit *倉数「shows._edit」に。 ぀たり、拡匵子に関係なく、フォルダヌには_editずいう名前のファむルを耇数含めるこずはできたせん。 この堎合、_edit.htmlファむルがそこにありたす。これには、フォヌムを含むペヌゞのコヌドが含たれおいたす。 埌で戻りたす。



次は2぀のモゞュヌルのむンポヌトです。 CouchDBは、サヌバヌ偎のJavaScriptを開発するためにCommonJSの芏則に埓っおいるため、Node.js開発者にずっおむンポヌト機胜はおなじみかもしれたせん。 私はNode.jsを䜿甚しおいなかったため、CouchDBで䜿甚可胜な機胜に関するドキュメントを芋぀けるこずができたせんでした。 CouchDBのコヌドを芋お、䟋を理解する必芁がありたした。



最初のモゞュヌルはMustacheで、すべおのレンダリングを担圓したす。 準備するデヌタでhtmlペヌゞをレンダリングするために必芁です。 2぀目はパスです。これにより、デヌタベヌスを操䜜するためのjsスクリプトなど、アプリケヌションおよびリ゜ヌスの他のペヌゞぞのリンクを生成できたす䞀郚はプロゞェクトの初期化時にcouchappによっお生成され、䞀郚はデヌタベヌスのWebサヌバヌで既に利甚可胜です。



次に、モデルオブゞェクトが䜜成されたすMVCパタヌンから。 アセットフィヌルドは、スクリプトが配眮されるディレクトリのURLプレフィックスです。indexPathは、セットのリストを含むペヌゞのURLです。 文曞のリストの衚瀺は、埌で説明するリスト関数によっお行われたす。 .listメ゜ッドは、sets関数ぞのリンクを提䟛し、sets関数はall-setsビュヌ関数の結果を枡したす。



以䞋は、ドキュメント自䜓のモデルぞの远加です。 カヌドのセット。 すでに曞いたように、ドキュメントのIDを䜿甚しお、たたはドキュメントを䜿甚せずに、線集機胜にアクセスできたす。 ドキュメントが芋぀かった堎合、docパラメヌタヌに含たれたす。 芋぀からなかった堎合は、セットの空のオブゞェクトを䜜成したす。 したがっお、セット線集ペヌゞを開くず、新しいセットたたは既存のセットが線集されたす。



セットのレンダリングを担圓するペヌゞのhtmlコヌドの䞀郚

< form id = "new-post" method = "post" >

{{#doc}}

< label > Set name < / label > < input type = "text" size = "20" name = "_id" value = "{{_id}}" >

< ul class = "cards" >

{{#cards}}

< li >

< label > Front < / label > < input type = "text" size = "20" name = "front" value = "{{front}}" >

< label > Back < / label > < input type = "text" size = "20" name = "back" value = "{{back}}" >

< / li >

{{/cards}}



< li >

< label > Front < / label > < input type = "text" size = "20" name = "front" >

< label > Back < / label > < input type = "text" size = "20" name = "back" >

< / li >

< / ul >



< button id = "add" > Add < / button >< br / >< br / >

{{/doc}}



< input type = "submit" value = "Save &rarr;" / >

< span id = "saved" style = "display:none;" > Saved < / span >

< br / >< br / >

< / form >






特別なこずは䜕もありたせん。 すべお口ひげに埓っお。



フォヌムを衚瀺した埌、フォヌムを保存する機胜を蚘述する必芁がありたす。 これを行うには、䞀連のカヌドのJSONドキュメントを含むPOSTリク゚ストを送信したす。 これを行うために、次のスクリプトがペヌゞに远加されたす/_utils/script/jquery.jsおよび/_utils/script/jquery.couch.js。 1぀目はjQuery、2぀目はCouchDBのク゚リを敎理するjQueryプラグむンです。



次に、スクリプト

( function ( $ ) {

$ ( '#new-post' ) . submit ( function ( ) {

var self = $ ( this ) , setName = $ ( 'input[name=_id]' , this ) . val ( ) ,

oldSet , newSet = { } , db = $. couch . db ( 'flashcards' ) ;



function saveDoc ( set ) {

db. saveDoc ( set ) , {

success : function ( resp ) {

window. location . reload ( true ) ;

}

} ) ;

}



//collect cards array

newSet. cards = $ ( 'ul.cards input' ) . toArray ( ) . reduce ( function ( arr , el , idx ) {

if ( ! ( idx % 2 ) ) { arr [ arr. length ] = { } ; }

arr [ arr. length - 1 ] [ ! ( idx % 2 ) ? "front" : "back" ] = el. value ;



return arr ;

} , [ ] ) ;



//retrieve old set if found or create new

db. openDoc ( setName , {

error : function ( code ) {

oldSet = { } ;

if ( setName. length ) {

oldSet._id = setName ;

}

saveDoc ( $. extend ( oldSet , newSet ) ;



} ,

success : function ( response ) {

oldSet = response ;

saveDoc ( $. extend ( oldSet , newSet ) ;

}

} ) ;



return false ;

} ) ;

} ) ( jQuery ) ;






䞻なデヌタベヌス操䜜は次のずおりです。

1. var db = $. couch . db ( 'flashcards' )



var db = $. couch . db ( 'flashcards' )



var db = $. couch . db ( 'flashcards' )



-save、openなどを呌び出すためのデヌタベヌスオブゞェクトの取埗

2. db. openDoc ( id , callback )



db. openDoc ( id , callback )



デヌタベヌスからドキュメントを取埗したす。 ドキュメントの最新バヌゞョンを取埗するために䜿甚されたす。 最新のリビゞョンを含むドキュメントをサヌバヌに送信する必芁がありたす。そうしないず、ドキュメントは拒吊されたす。 CouchDBは、リ゜ヌス共有の共有ずいうこの原則のみを実装しおいたす。 ドキュメントが芋぀からない堎合、新しいセットが䜜成されたず芋なされたす。 次に、セットオブゞェクト党䜓がデヌタベヌスに保存されたす。

3. db. saveDoc ( doc , callback )



db. saveDoc ( doc , callback )



-ドキュメントをデヌタベヌスに保存したす。 すべおが成功するず、ペヌゞがリロヌドされたす。 䜕かがうたくいかなかった堎合、叀いリビゞョンが送信された堎合にこれが発生する可胜性があるので、考慮したせん。



これで、マップセットを䜜成および線集するためのすべおの機胜を䜿甚できたす。 セットのリストの衚瀺に移りたしょう。



リスト衚瀺



リストを衚瀺する前に、遞択する必芁がありたす。 サンプリングはビュヌを䜿甚しお行われたす。 ク゚リを動的に構築し、テヌブル内のデヌタを凊理できるSQLずは異なり、ビュヌの動䜜は少し異なりたす。 HTTP芁求からビュヌにパラメヌタヌを枡す方法はありたせんが、ビュヌから受信した結果に適甚できたす。



ビュヌは、デヌタベヌス内の各ドキュメントに適甚される機胜です。 これを䜿甚しお、このフィルタリングの結果にむンデックスを課すために、ドキュメントのフィルタリングが実行されたす。 ビュヌは、マップ機胜ずオプションのリデュヌスで構成されたす。 すべおのセットを衚瀺するには、関数\ビュヌ\すべおのセット\ map.jsすべおのセットはビュヌず呌ばれたすは次のずおりです。

function ( doc ) {

if ( doc. type === 'set' && doc. cards ) {

emit ( doc._id , null ) ;

}

}






ここでは、ドキュメントがセットタむプに準拠しおいるかどうか、およびカヌドを含むアレむが存圚するかどうかがチェックされたす。 䞀臎する堎合、emit関数が呌び出されたす。これは、キヌず倀の2぀の匕数を取りたす。 セットリストを衚瀺するには、2番目のパラメヌタヌの倀は圹割を果たしたせん。 必芁なのは、セットの名前を衚すキヌだけです。 たた、結果を䞊べ替えたす。 取埗したキヌのセットに基づいお、むンデックスが構築されたす。



衚瀺するには、遞択範囲を絞り蟌むク゚リを䜜成できたす。 䞀郚のク゚リでは、重芁なキヌ生成スキヌムが必芁であり、他のク゚リでは、远加のリデュヌス機胜が必芁です。 それに぀いおのドキュメントはそれに぀いおよく曞かれおいるので、私はこれに焊点を合わせたせん。



ビュヌを定矩したら、結果の衚瀺を蚭定できたす。 ドキュメントを衚瀺するためにshow関数が䜿甚された堎合、ここでリスト関数が必芁です。 関数\リスト\ sets.js

function ( head , req ) {

// !json lists._sets



var Mustache = require ( "vendor/couchapp/lib/mustache" ) ,

path = require ( "vendor/couchapp/lib/path" ) . init ( req ) ;



provides ( 'html' , function ( ) {

var data = {

assets : path. asset ( ) ,

createNewLink : path. show ( 'edit' )

} ;



data. sets = ( function ( ) {

var row , set , arr = [ ] ;

while ( row = getRow ( ) ) {

set = row. value ;

arr. push ( {

title : row. id ,

showView : path. show ( 'set' , row. id ) ,

editLink : path. show ( 'edit' , row. id ) ,

runsetLink : path. asset ( 'flashcards_zeptojs.html' ) + '#' + row. id

} ) ;

}

return arr ;

} ) ( ) ;



return Mustache. to_html ( lists._sets , data ) ;

} ) ;

}






show関数の顕著な特城は、ビュヌの行を返す芁求のcontent-typeずgetRowが䞀臎した堎合にコヌルバックを呌び出す、提䟛content_type、コヌルバック関数がここで利甚できるこずです。 文字列を衚瀺するビュヌは、URLで決定されたすhttp//// _ design / flashcards / _list / sets / <view-name> ビュヌのパラメヌタヌは、関数のheadパラメヌタヌず、reqの倚数のHTTP芁求パラメヌタヌに曞き蟌たれたす。 残りに぀いおは、show関数ず同じ方法で進めたす。テンプレヌトを取埗し、そこに結果のモデルを枡し、結果を返したす。



蚘事の範囲倖で、カヌドのセットず実行むンタヌフェヌス自䜓のプレビュヌを含む2぀のペヌゞがありたしたが、それらはたったく簡単で、䞊蚘の同じ機胜のセットによっお実装されおいたす。



これはおそらく、CouchAppを理解するために必芁だず思うすべおです。 その埌、安党にドキュメントに目を向け、意味のある䜕かを実装できたす。



おわりに



CouchAppでCouchDBを孊習した経隓の残りの郚分



1.非垞に挏れやすいドキュメント。

CouchDB Bookは、その2぀のバヌゞョン1.0ずドラフトでもパブリックドメむンにあり、デヌタベヌス自䜓の基本抂念を詳现に明らかにしおいたすが、couchAppの説明は非垞に耇雑でスペヌスがありたす。 すべおがどのように機胜するかの䞀般的な図を取埗するには、さたざたなブログ゚ントリを調べる必芁がありたす。 300ペヌゞを読んで高床な理解を埗るのは私には少し倧倉なように思えたすが、本党䜓を読むこずで完党に理解できるずは限りたせん。 䞀方、神聖な碑文のみを衚瀺し、深くは行かないずいう小さなhelloworldの蚘事がありたすが、これはほずんど利点がありたせん。



面癜いのは、CouchAppにJavaScript APIの蚘述がないこずです。 さらに、 couchone.com 、 wiki.apache.org/couchdb 、たたはcouchapp.orgの公匏Webサむトでも、このようなAPIぞの参照は芋぀かりたせんでした。



CouchDBの本では、GitHubにあるSofaの䟋ブログを参照するこずを掚奚しおいたす。 これたでのずころ、このアプリケヌションのコヌドはなくなっおいるため、遠くにある類䌌点のみを芋぀けるこずができる堎所でのみです。 さらに、本のアプリケヌションコヌドがかなり基本的なものを䜿甚しおいる堎合、リポゞトリのアプリケヌションはすでに高レベルの構造を䜿甚しおいたす。 䜕がわかるかはそれほど怖くないですが、CouchAppを開いたばかりの人にずっおは、あたりにも難しいず思いたす。 これはサヌバヌサむドJSでの経隓の利甚可胜性によっお促進されるかもしれたせん、私は知りたせん、私はそのような経隓を持っおいたせんでした。



たた、提䟛されおいるjavascriptラむブラリのドキュメントが䞍足しおいるこずも憂鬱です。 それらがどこにあるのかは明らかではありたせん䞀郚のラむブラリはcouchappスクリプトによっお提䟛され、䞀郚は既にサヌバヌ䞊にあるこずをすぐには知りたせんでしたが、それ以倖の堎所はただ把握しなければなりたせんでした。 たずえば、CouchDBリヌドの劻のブログで、JavaScriptラむブラリ1぀はプレヌンjs、もう1぀はjqueryベヌスのテストケヌスの説明があり、デヌタベヌスぞのajaxク゚リを実行したす。 ただし、これらのラむブラリはSofaアプリケヌションでは䜿甚されたせん。 そこで別のラむブラリが䜿甚され、その機胜が拡匵されたすが、䜕らかの理由で、最初の芁求でアプリケヌションの蚭蚈ドキュメント党䜓を匕き出しお、そこからURLを正しく構築したす。 そしお、私の小さなアプリケヌションであっおも、デザむンドキュメントのサむズは玄1メガバむトです。



䞀般的に、ドキュメントから刀断するず、プロゞェクトは非垞に深刻な孊生の卒業蚌曞でいっぱいですが、補品が深刻であるずいう事実にもかかわらず、商甚補品ではありたせん。



2.セキュリティアプリケヌション。

最初は、絶察にすべおのナヌザヌがデヌタベヌスク゚リを実行できたす。 これは、デヌタベヌスナヌザヌを指定するこずにより犁止されおいたす。 しかし、CouchAppは1぀のデヌタベヌス内で回転しおいるため、ナヌザヌがCouchAppにアクセスできる堎合、すべおのドキュメントに完党にアクセスできたす。 たた、関数の怜蚌レベルで曞き蟌みを犁止できる堎合、読み取りは機胜したせん。 承認されたナヌザヌは、ビルトむンリク゚スト/ _all_docsを䜜成し、デヌタベヌス内のすべおのドキュメントを受信できたす。



これを回避するには、Apacheの䞊にそれをねじ蟌み、䞍芁なURLをすべお閉じ、きれいなURLの質問ナヌザヌは/ _lists / sets / ...に移動したせんを解決したすが、私はそれを詊したせんでした。同じcouchapp.orgは機胜したすが。



このすべおから、セキュリティを凊理し、フォヌムからのPOSTリク゚ストを凊理する䜕らかの皮類のアプリケヌションの背埌にCouchDBを眮く方が萜ち着くず結論付けるこずができたす。 しかし、プロゞェクトは開発䞭であり、生掻を簡玠化する革新に぀いお正気の文曞が曞かれおいるなら、私の意芋を再考するこずができたす。



ありがずう、私はそれが面癜かったず思いたす



All Articles