本日はvte.cxのコンテンツ管理について説明します。
BaaSに求められるCMS機能
ほとんどのBaaSはバックエンドのAPIを提供するだけでHTMLやCSS、JavaScript、画像といったコンテンツは扱えません。
なかにはWebシステムを想定したバックエンドのAPIを提供するものもありますが、オリジンが異なるためクロスドメイン対策が必要になります。
そもそもHTMLコンテンツとAPIが異なるドメインになるのはセキュリティ面でも運用面でも筋が悪いように思います。それに、別途、Webコンテンツをホスティングするためのサーバも必要になります。
vte.cxは本格的なWebシステムを構築するためのBaaSであり、コンテンツもデータと同じリソースとして扱えるのが特徴です。つまり、コンテンツもデータも同じドメインから取り出すことができ、CMS(Content Management System)としての機能を備えています。コンテンツを置くためのサーバはもう必要ありません。
これにより、コンテンツもAPIも同じオリジンになるため、一般的なWebアプリケーションと同様の普通の開発できるようになります。
#ATOM EntryのContentでコンテンツを管理する
vte.cxではコンテンツをATOM Entryで管理しています。
EntryのcontentタグにはHTMLやJavaScript、画像などのコンテンツを格納することができます。
この項目がセットされている場合、?fや?eなどのURLパラメータをつけないでGETすると格納されているコンテンツそのものを取得することができます。つまり、HTMLや画像などを表示したりすることが可能なわけです。
このことからも、vte.cxではデータとコンテンツを区別することなく扱えるCMSとしての機能があることがわかります。
content-typeもセットすることができます。
content-typeがtext/で始まるものであれば、HTMLエンコーディングされた状態でセットされます。その他はバイナリとしてBase64変換した文字列がセットされます。
より詳しい説明は、ドキュメントの内部コンテンツを参照してください。
#将来的なコンテンツ管理の分離
現在はコンテンツをデータと同じデータストアに登録していますが、ラージオブジェクトなどを管理するために別途ストレージを用意することを考えています。
そのストレージにはAmazon S3やGoogle Cloud Storageといったクラウドのストレージサービスを想定しています。管理画面でユーザが選択したストレージサービスを接続すれば自由に容量の際限なく登録できる仕組みになる予定です。
#コンテンツの登録とrxcp.shの詳細
コンテンツの登録では、POSTかPUTでURLパラメータに?_content
をつけて実行します。すると登録したデータがcontentタグの中に変換されて格納されます。データはどのようなフォーマットでも構いません。
?_content
をつけないで実行した場合は通常のFeed登録となります。
この場合、JSONかXML、MessagePackなどのフォーマットでなければエラーとなります。
vtecxblankにはデプロイのためのシェルスクリプト rxcp.sh が用意されています。
わずか40行ほどのbashシェルスクリプトですが、これだけでローカルにあるコンテンツを全てサーバにデプロイすることができます。
#!/bin/bash
function send() {
if [ -d $3 ]; then
echo "$3 is a directory."
curl -H "Authorization: Token "$1 -H "Content-Type:"$4 -H "Content-Length: 0" -X PUT $2$5?_content
else
curl -H "Authorization: Token "$1 -H "Content-Type:"$4 -T $3 $2$5$6
fi
echo -e '\n'
}
for file in `find $2`
do
echo -n $file' --> '
type="application/octet-stream"
case ${file##*/*.} in
"json" ) type="application/json" ;;
"xml" ) type="text/xml" ;;
"html" ) type="text/html;charset=UTF-8" ;;
"js" ) type="text/javascript;charset=UTF-8" ;;
"css" ) type="text/css;charset=UTF-8" ;;
"png" ) type="image/png" ;;
"gif" ) type="image/gif" ;;
"jpeg" ) type="image/jpeg" ;;
"jpg" ) type="image/jpeg" ;;
esac
tgt=${file#$2}
echo -n $3$tgt' '
opt=""
if [ -n "$4" ]; then
opt=?_$4
fi
send $1 $3 $file $type $tgt $opt
done
rxcp.shの動作
指定されたローカルフォルダ配下のコンテンツについて以下を再帰的に繰り返します。
- ディレクトリであればサーバにフォルダを作成します。(中身が0バイトで
?_content
がついていることに注意してください)curl -H "Authorization: Token "$1 -H "Content-Type:"$4 -H "Content-Length: 0" -X PUT $2$5?_content
- ファイルであればサーバにそれを登録します。(コンテンツかデータかは$6で決定します)
curl -H "Authorization: Token "$1 -H "Content-Type:"$4 -T $3 $2$5$6
実際にrxcp.shが呼ばれるのは、gulpコマンドかCircleCIの以下のコマンドからです。
./rxcp.sh ${accesstoken} dist https://{service name}.1.vte.cx content
./rxcp.sh ${accesstoken} setup https://{service name}.1.vte.cx/d
1行目のdistはビルド後のHTML、CSS、JavaScript等のコンテンツがあるディレクトリです。
2行目のsetupはサーバフォルダのACL設定やスキーマテンプレートなどがあるディレクトリです。
これはコンテンツではなくFeedとして登録されます。?_content
がつかないので注意してください。
以上で本日はおしまいです。
明日はトランザクション処理と採番処理について説明します。
それでは。