楽観的/悲観的ロック、トランザクション・パッチ処理（一括更新）・更新、作成　書き込み可能性

##楽観的ロック

```ruby:qiita.rb
＃条件付きPUT=1.GET（ETagを得るため）→2.PUT(得られたETagを使う、条件付きPUT=If-Match(下図))
#1.リクエスト 
GET /1120002 HTTP/1.1
Host: zip.ricollab.jp
↓
#1.リスポンス
HTTP/1.1 200 OK
Content-Type: application/json
ETag: sample-etag-value

{
    "zipcode": "1120002",
    "address": {
        "prefecture": "東京都",
        "city": "文京区",
        "town": "小石川",
},
"yomi": {
    "prefecture": "トウキョウト",
    "city": "ブンキョウク",
    "town": "コイシカワ",
　},
}


#2.リクエスト　条件付きPUT=1.GET（ETagを得るため）→2.PUT(得られたETagを使う、条件付きPUT=If-Match(下図))
PUT /1120002 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
If-March: sample-etag-value

{
    "zipcode": "1120002",
    "address": {
        "prefecture": "東京都",
        "city": "文京区",
        "town": "小石川",
},
"yomi": {
    "prefecture": "トウキョウト",
    "city": "ブンキョウク",
    "town": "コイシカワ",
　},
}
↓
#2.リスポンス
HTTP/1.1 200 OK

#条件付きGET/PUT/DELETEとヘッダ対応
| メソッド         |     Last-Modified |        ETag        |
| GET              |If-Modified-Since  |       If-None-Match|
| PUT/DELETE       |If-Unmodified-Since|       If-Match     |


#リクエスト 削除
DELETE /1120002 HTTP/1.1
Host: zip.ricollab.jp
Content-Type: application/json
If-March: sample-etag-value
↓
#リスポンス
HTTP/1.1 200 OK

``` 
##条件付きGET/PUT/DELETEとヘッダ対応
| メソッド         |     Last-Modified |        ETag        |
| GET              |If-Modified-Since  |       If-None-Match|
| PUT/DELETE       |If-Unmodified-Since|       If-Match     |


-----------------------------------------------
##悲観的ロック

```ruby:qiita.rb
#リクエスト
LOCK /1120002 HTTP/1.1
Host: zip.ricollab.jp
Timeout: Second-3600
Content-Type: application/xml; charset=utf-8
Authorization: Basic ...

<D:lockinfo xmlns:D="DAV">
<D:lockscope><D:exclusive/></D:lockscope>
<D:lockscope><D:write/></D:lockscope>
</D:lockinfo>

------------------

イメージ
LOCK→
←200OK
GET→
←200OK
　　　　　　　　←GET
　　　　　　　　200OK→
PUT(by_a)→
←200OK
　　　　　　　　←PUT(by_b)
　　　　　　　　→200OK
GET→
←200OK
UNLOCK→
←200OK

---------------

#リスポンス
<D:prop xmlns:D="DAV">
	<D:lockdiscoverry>
		<D:activelock>
			<D:lockscope><D:exclusive/></D:lockscope>
			<D:lockscope><D:write/></D:lockscope>
			<D:depth>Infinity</D:depth>
			<D:owner>
				<D:href>mailto:yohei@gmail.com</D:href>
			<D:owner>
			<D:timeout>Second-3600</D:timeout>
			<D:lockstoken>
				<D:href>opaquelocktoken:e71d4fae-5dec-22d6-fea5</D:href>
			</D:lockstoken>
		</D:activelock>
	</D:lockdiscoverry>
</D:prop>
``` 
```ruby:qiita.rb
#ロック機能確認
#リクエスト　リソース編集　（失敗　Ifヘッダでロックトークンを指定しなかった場合）
↓
#リスポンス
HTTP/1.1 423 Locked

---------
#リクエスト（成功）
PUT /1120002 HTTP/1.1
IF:(<opaquelocktoken:e71d4fae-5dec-22d6-fea5>)
Content-Type: application/json

{
    "zipcode": "1120002",
    "address": {
        "prefecture": "東京都",
        "city": "文京区",
        "town": "小石川",
},
"yomi": {
    "prefecture": "トウキョウト",
    "city": "ブンキョウク",
    "town": "コイシカワ",
　},
}
↓
#リスポンス
HTTP/1.1 200 OK
``` 

```ruby:qiita.rb
#リクエスト　（ロック解除）
UNLOCK /1120034 HTTP/1.1
Host: zip.ricollab.jp
Content-Type: application/xml; charset=utf-8
Authorization: Basic ...
Lock-Token: opaquelocktoken:e71d4fae-5dec-22d6-fea5
↓
#リスポンス　
HTTP/1.1 200 OK 
``` 
 

```ruby:qiita.rb
#リクエスト　（ロックしたいURIのみ、×WebDAVのデータモデルに適用、LOCK対象の子リソースPOST）
POST /1120034 HTTP/1.1
Host: zip.ricollab.jp
Content-Type: application/x-www-form-urlencoded
Authorization: Basic ...
scope=exclusive&timeout=300
↓
#リスポンス
HTTP/1.1 201 Created
Location: http://zip.ricollab.jp/1120034/lock
Content-Type: application/json

{
    "locktype": "exclusive",
    "timeout": "2010-09-07T10:00:30Z",
    "owner": "yohei",
}


#ロック削除
DELETE /1120034/lock HTTP/1.1
Host: zip.ricollab.jp
Authorization: Basic ...
↓
HTTP/1.1 200 OK
```




##トランザクション（失敗時に元の状態に戻せる、金銭取引等に使われる）
```ruby:qiita.rb
http://zip.ricollab.jp/transactions
↓POST送信
#リクエスト
POST /transaction/308 HTTP/1.1
Host: zip.ricollab.jp
#レスポンス
HTTP/1.1 201 Created
Location: http://zip.ricollab.jp/transactions/308

------

#リクエスト（PUT>POST頻出度）+/1追加
PUT /transaction/308/1 HTTP/1.1
Host: zip.ricollab.jp
↓
#リスポンス　+/1追加
HTTP/1.1 201 Created
Location: http://zip.ricollab.jp/transactions/308/1

------
#リクエスト
PUT /transaction/308 HTTP/1.1
Host: zip.ricollab.jp
+ Content-Type: application/x-www-form-urlencoded

+commit=true
↓
#リスポンス　OK/ERROR
HTTP/1.1 200 OK
HTTP/1.1 500 Internal Server Error
``` 

```ruby:qiita.rb
#トランザクション　削除
DELETE /1120002 HTTP/1.1
Host: zip.ricollab.jp
↓
HTTP/1.1 200 OK
``` 

```ruby:qiita.rb
#パッチ処理　トランザクション　POST一括削除
PUT /batch HTTP/1.1
Host: zip.ricollab.jp
Content-Type: application/xml; charset=utf-8

DELETE /1
DELETE /2
DELETE /3
``` 

##パッチ処理（一括更新）
###リクエスト　PUT（一括更新）
```ruby:qiita.rb
PUT /9999999 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
    "zipcode": "9999998",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}

{
    "zipcode": "9999999",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
``` 
###レスポンス　XML　（複数の<D:status>に、ひとつひとつステータスコードを返す）
```ruby:qiita.rb
HTTP/1.1 200 OK
Content-Type: application/json

<D:multistatus xmlns:D="DAV:">
	<D:response>
		<D:href>http://zip.ricollab.jp</D:href>
		<D:propstat>
			<D:status>HTTP/1.1 200 OK<D:status>
		</D:propstat>
		<D:propstat>
			<D:status>HTTP/1.1 200 OK<D:status>
			<D:responsedescription>
			データベース接続エラーです。
			</D:responsedescription>
		</D:propstat>
	</D:response>
			<D:responsedescription>
			全２つのリクエスト中１つが成功しました。
			</D:responsedescription>
</D:multistatus>
``` 
### レスポンス JSON（複数のstatusに、ひとつひとつステータスコードを返す）
```ruby:qiita.rb
HTTP/1.1 200 OK
Content-Type: application/json

[
 {
	"status": "200 OK",
	"description: "成功しました。"
 },
 {
	"status": "500 Internal Server Error",
	"description: "データベース接続エラーです。"
 }
]
``` 

 
##更新 PUT
###バルクアップデート　PUT　更新
 ```ruby:qiita.rb
PUT /9999999 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
    "zipcode": "1120002",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
``` 
###パーチャルアップデート　PUT　更新
```ruby:qiita.rb
PUT /9999999 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
"yomi": {
    "prefecture": "aaト",
	}
}
``` 

 

 
 
##作成 POST/PUT
###リクエスト　POST
```ruby:qiita.rb
POST /9999999 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
    "zipcode": "9999999",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
```
###リスポンス POST
```ruby:qiita.rb
HTTP/1.1 201 Created
Content-Type: application/json/9999999

{
    "zipcode": "9999999",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
``` 
###リクエスト　PUT
```ruby:qiita.rb
PUT /9999999 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
    "zipcode": "9999999",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
```
###リスポンス PUT
```ruby:qiita.rb
HTTP/1.1 201 Created
Content-Type: application/json

{
    "zipcode": "9999999",
    "address": {
        "prefecture": "aa都",
        "city": "bb区",
        "town": "ccc",
},
"yomi": {
    "prefecture": "aaト",
    "city": "bbク",
    "town": "ccc",
　},
}
``` 
### CRUD-HTTP
| Create           |              作成 |       POST/PUT     |
| Read             |          読み込み |        GET         |
| Update             |              更新 |         PUT        |
| Delete             |              削除 |       DELETE       |
GET,POST,PUT,DELETE,HEAD,OPTION,TRACE,CONNECT
###httpヘッダ
Content-Type（メディアタイプ）,charset（文字のエンコーディング）,Authorization(Basic認証、ユーザー名とパスワード),If-None-Match(条件付きGET、ETagを条件にする),Content-discription(ファイル名を指定する)
###ステータスコード
200 OK リクエスト成功、500 InternalServerError　サーバー内部エラー
###URI
.json(拡張子),/2010/05/01(マトリクスURI)