RESTful API
RESTful API
RESTful API (REST API) は、RESTに基づいたAPIのことです。
REST
RESTとは、REpresentational State Transferのことで、ロイ・フィールディング氏によって提唱されました。
RESTには、次のような原則があります。
- ステートレスなクライアント/サーバプロトコル
HTTPメッセージの一つ一つが、そのリクエスト(メッセージ)を理解するために必要な全ての情報を含む。そのため、クライアントもサーバも、メッセージ間におけるセッションの状態を記憶しておく必要がない。ただし実際には、多くのHTTPベースのアプリケーションはクッキーやその他の仕掛けを使ってセッションの状態を管理している(URLリライティングのような一部のセッション管理手法を使うシステムは、RESTfulではない)。- すべての情報(リソース)に適用できる「よく定義された操作」のセット
HTTP では操作(メソッド)の小さなセットが定義されている。最も重要なのは "GET"、"POST"、"PUT"、"DELETE" である。これらはデータ永続化に要求されるCRUDと比較されることがある。もっとも "POST" に関してはCRUDにはぴったり対応していない。- リソースを一意に識別する「汎用的な構文」
RESTfulなシステムでは、すべてのリソースはUniform Resource Identifier (URI) で表される一意的な(ユニークな)アドレスを持つ。- アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
RESTシステムでは、多くの場合、HTML文書またはXML文書を使う。こうした文書に情報およびその他のリソースへのリンクを含める。こうすることにより、あるRESTリソースから他のRESTリソースを参照したい場合は単にリンクを辿るだけでよい。レジストリなどの他の基盤的な機能を使う必要はない。
Representational State Transfer - Wikipedia
REST APIの特徴
URIでリソースを指定
REST APIでは、URI (エンドポイント)でリソースを指定します。
例えば、ユーザー(User)に対して操作をする場合はhttp://example.com/api/user
、
投稿(Post)に対して操作する場合はhttp://example.com/api/post
のようになります。
HTTPメソッドで処理を指定
先に述べたように、REST APIではURIでリソースを指定します。
そして、そのリソースに対してどのような処理を行うかをHTTPメソッドで指定します。
HTTPメソッドには、GET, POST, PUT, PATCH, DELETE
などがあります。
これらはそれぞれ、取得、作成、更新、更新、削除、として一般的に使われます。
REST APIの例
- ユーザー一覧の取得
エンドポイント http://example.com/api/user
HTTPメソッド GET
- ユーザーの新規追加
エンドポイント http://example.com/api/user
HTTPメソッド POST
- ユーザー情報の更新
エンドポイント http://example.com/api/user
HTTPメソッド PATCH
- ユーザーの削除
エンドポイント http://example.com/api/user
HTTPメソッド DELETE
α. 投稿に関する処理
上で示したユーザーの例で、エンドポイントをhttp://example.com/api/post
に変更する。
終わり
DockerでMongoDB永続化
DockerでMongoDB永続化
DockerでMongoDBサーバーを立てていて、そのデータを永続化する方法をまとめていきます。
Dockerは、docker-composeを使って設定していきます。
DockerでMongoDBを永続化するには、ボリュームの設定をして、/data/db
にマウントするだけです。
今回はdocker-composeを使って設定するので、volumes
に設定を書きます。
version: '3' services: db: image: mongo volumes: - db_data:/data/db volumes: db_data:
これで、設定は完了です。
あとは、docker-compose up
すると、そのMongoDBのデータは永続化されました。
終わり
RailsでMongoDBを使う
Mongoid
RailsでMongoDBを使うには、Mongoidを利用します。
Mongoidは、RubyのMongoDB用ORMです。
RailsでRDBを利用する場合、Active Recordが広く使われていますが、それのMongoDB版だということです。
Mongoidは、Active Recordと似たようなインターフェースがあり、Active Recordを使ったことがある人は使いやすいと思います。
実際に試してみる
Mongoidのインストール
では、実際にMongoidを使っていきます。
まず、Railsプロジェクトの作成時に、--skip-active-record
オプションをつけることで、Active Recordをスキップします。
それと同時に、通常のRDB関連のGemもインストールしません。
$ rails new . --skip-active-record --force
MongoidはGemでインストールできるので、Gemfileに追記して、bundle install
します。
gem 'mongoid'
bundle install
すると、Mongoidのインストールは完了です。
RailsでMongoidを使う
rails g scaffold
で一気にいろいろ生成します。
$ docker-compose run rails rails g scaffold user name age:integer --timestamp
これで、Userモデルやそのコントローラが作成されました。
ルーティングも自動で設定されています。
http://localhost:3000/usersにアクセスすると、↑のようなページが表示されました。
(ユーザー追加してます)
Mongoidのモデルの使用例
先に説明した方法で生成されたモデルの使用例をいくつかみてみます。
(それぞれ抜粋です)
# 新規作成 @user = User.new(user_params) # 更新 @user.update(user_params) # 消去 @user.destroy # 検索 @user = User.find(params[:id])
見てわかる通り、ActiveRecordとほぼ同様の方法で操作できます。
ただし、MongoDBでは結合ができないため、Mongoidのモデルでも結合ができません。
その他にも、いくつかActive Recordと異なる点があります。
終わり
MongoDBに認証を設定する
MongoDBに認証を設定する
MongoDBはデフォルトでは認証が設定されていません。
つまり、MongoDBに接続できれば、誰でもDBを操作することができてしまいます。
このままでは、セキュリティ的に大問題なので、ユーザー認証を設定し、ログインしないとDB操作できないようにします。
管理ユーザーを作成する
まず、はじめに、データベース全体を管理する管理ユーザーを作成します。
管理ユーザーはadmin
データベースに作成します。
ユーザーの作成はcreateUser()
です。
use admin db.createUser({ user: "admin", pwd: "password", roles: [ { role: "userAdminAnyDatabase", db: "admin" }, ] })
やっていることは、use admin
でadminデータベースを選択し、createUser()
でユーザーを作成しているだけです。
権限として、userAdminAnyDatabase
を指定することで、
各データベースの管理ユーザーとしています。
管理ユーザーでログイン
db.auth("ユーザー名", "パスワード")
でログインすることができます。
db.auth("admin", "password")
ログインに成功すれば1が返ってきます。
ログイン失敗時は0です。
一般ユーザーを作成
では、一般のデータベースを選択し、そのデータベースのユーザーを作成していきます。
ここでは、testというデータベースに一般ユーザーを作成しています。
use test db.createUser({ user: "user1", pwd: "password", roles: [ { role: "readWrite", db: "test" }, ] })
認証をONにしてMongoDBを起動
ユーザーを作成できたので、MongoDBのアクセスに認証を必要とします。
サーバーの起動時に、--auth
オプションを付けることで、認証が必要になります。
$ mongod --auth
mongoコマンドでログインする
mongo
コマンドでアクセスする場合、-u
オプションでユーザー名、-p
オプションでパスワードを設定することでログインすることができます。
このとき、--authenticationDatabase
でデータベースを指定します。
$ mongo -u "user1" -p "password" --authenticationDatabase "test"
終わり
MongoDBでインデックス
MongoDBでインデックスを作成する
インデックスを確認
この時点でのインデックスを確認してみます。
インデックスの確認には、getIndexes()
を使います。
> db.User.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
_id
が1になっています。
これは、_id
属性に対して昇順でインデックスが張られていることを示しています。
インデックスを作成
では、インデックスを作成していきます。
インデックスの作成は、createIndex
で行います。
> db.User.createIndex({ name: 1 }) { "numIndexesBefore" : 1, "numIndexesAfter" : 2, "createdCollectionAutomatically" : false, "ok" : 1 }
name: 1
を引数として渡しています。
これは、name
属性を昇順でインデックス作成することを示しています。
インデックスが作成できたので、再度インデックスを確認してみます。
> db.User.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "name" : 1 }, "name" : "name_1" } ]
name
の昇順インデックスが追加されていることが確認できました。
createIndex
の引数には、複数のキーを渡すことができ、その場合は複合インデックスとなります。
終わり
MongoDBを触ってみる
MongoDBを触る準備
今回は、Docker-Composeを使ってMongoDBをセットアップしました。
docker-compose.ymlの中身は↓です。
version: '3' services: mongo: image: mongo
あとは、docker-compose up
したら、MongoDBのサーバーが立ちました。
docker-compose exec mongo bash
で中に入り操作していきます。
MongoDBを触ってみる
MongoDBをインストールできたら、mongo
コマンドでMongoDBを操作することができます。
$ mongo
DB作成・選択
use DB名;
とするだけです。
DBの選択だけでなく、作成も自動で行われます。
> use Sample; switched to db Sample
これでSampleというデータベースを作成できました。
show dbs;
でDB一覧を確認することができます。
コレクションの作成
RDBのテーブルにあたるところのコレクションを作っていきます。
コレクションを作成するには、createCollection()
を使います。
> db.createCollection('User'); { "ok" : 1 }
コレクションを作成できました。
show collections;
でコレクションの一覧を確認できます。
データの追加
insert()
を使って、データを追加します。
JSON形式で渡せば、すきな属性を付与することができます。
> db.User.insert({name: 'Ken', age: 10}) WriteResult({ "nInserted" : 1 }) > db.User.insert({name: 'Mari', gender: 'f'}) WriteResult({ "nInserted" : 1 })
データの一覧を取得
データの一覧を取得して、データが追加されていることを確認します。
データの取得には、find()
を使う
> db.User.find() { "_id" : ObjectId("611681fa60f9dd4792a46c02"), "name" : "Ken", "age" : 10 } { "_id" : ObjectId("6116821a60f9dd4792a46c03"), "name" : "Mari", "gender" : "f" }
find()
の第一引数には、条件を指定することができます。
> db.User.find({ gender: 'f' }) { "_id" : ObjectId("6116821a60f9dd4792a46c03"), "name" : "Mari", "gender" : "f" }
また、演算子も利用できます。
> db.User.find({ age: { $lt: 15 }}) { "_id" : ObjectId("611681fa60f9dd4792a46c02"), "name" : "Ken", "age" : 10 }
find()
の第二引数で取得したい属性を指定できます。
> db.User.find({}, { name:1, _id:0 }) { "name" : "Ken" } { "name" : "Mari" }
データの更新
データの更新はupdate()
でできます。
第一引数が条件、第二引数が更新内容です。
> db.User.update({name: 'Ken'}, {age: 15}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.User.find() { "_id" : ObjectId("611681fa60f9dd4792a46c02"), "age" : 15 } { "_id" : ObjectId("6116821a60f9dd4792a46c03"), "name" : "Mari", "gender" : "f" }
今回はここまで!
終わり
MongoDB
MongoDB
MongoDBは、ドキュメント型のNoSQLデータベースです。
C++で開発されていて、人気のあるデータベースの一つです。
「MongoDBでは、どのようにデータを保存・管理しているの?」
MongoDBはドキュメント型のNoSQLです。
MongoDBでは、JSONのような「ドキュメント」という形式でデータを格納します。
RDBのテーブルとは異なりスキーマがないため、柔軟なデータを格納することができます。
そして、「ドキュメント」を集めたものが「コレクション」です。
複数のドキュメントを束ねて、一つのコレクションとして扱います。
「MongoDBの強みと弱みは?」
MongoDBは、次のような強みがあります。
- JSON形式で階層型データを扱える
MongoDBはJSON形式でデータを格納するため、階層型のデータを格納できます。
また、きちっと決められたスキーマがあるわけではないため、柔軟なデータを扱うことができます。 - 強力なインデックス
セカンダリインデックスや複合キーインデックス、マルチキーインデックスといった便利なインデックスがあります。 - SQLに似せたクエリで扱いやすい
NoSQLであるMongoDBですが、SQLに似たクエリで、扱いやすいです。 - 水平分割・複製が容易
ドキュメント型のNoSQLであるMongoDBは、水平分割や複製が容易にできます。
一方で、MongoDBには次のような弱みもあります。
- トランザクションがなく、一貫性を保証できない
MongoDBでは、複数のドキュメントを一貫性を保って更新することはできません。
そのため、複数ドキュメントで一貫性を保証する必要がある場合、利用できません。 - 結合ができない
MongoDBでは、ドキュメントの結合をすることができません。
そのため、複数ドキュメントの内容を統合して処理する場合、アプリケーション側で実装する必要があります。 - スキーマがないため、データ型が不定
MongoDBはスキーマがありません。
そのことは、柔軟に様々な形式のデータを扱えるといったメリットがある一方で、デメリットもあります。
スキーマがなく、キー名やデータ型が不明です。
そのため、保守性の低下といった問題があります。
これは動的型付け言語と似たようなイメージです。
終わり