機能

以下は,EveベースのAPIであっても開示可能な主要な特性リストである.

休みを大切にする

EVEプロジェクトは、可能な限り最適なREST互換APIを提供することを目的としています。ファンダメンタルズ. REST このような原則は 注目点分離 そして、 無状態階層システム そして、 可緩性 そして、 統一インターフェース. コアAPIを設計する際には考慮されている.

全方位CRUD作業

APIは全シリーズをサポートすることができます CRUD 運営部。同じAPIでは、1つのエンドポイントで読み取り専用リソースにアクセスすることができ、別のエンドポイントで完全に編集可能なリソースを持つことができます。次の表にEveがRESTによりCRUDを実現する過程を示す。

行くぞ!

HTTP動詞

文脈.

創造する.

POST

集合

創造する.

PUT

公文.

代わる

PUT

公文.

読んでみて

取りに行ってヘイダー

集合/文書

更新

PATCH

公文.

削除

DELETE

集合/文書

HTTPを上書きする方法

これらの手法をサポートしない零細クライアントのバックアップとして,APIは喜んでサポートする. X-HTTP-Method-Override お願いします。例えば、クライアントはサポートされていません PATCH 方法は1つの POST 使用 X-HTTP-Method-Override: PATCH ヘディングです。そして、このAPIは実行される PATCH ,元の要求方法を上書きする.

カスタマイズ可能なリソースエンドポイント

デフォルトの場合,Eveは既知のデータベース集合をリソースエンドポイント(REST慣用用法における永続的識別子)として提供する.1つのデータベースは people コレクションは example.com/people APIエンドポイント。しかし、URIをカスタマイズすることができ、例えば、APIサイトを変更することができます。 example.com/customers/overseas それがそうです。以下の要請を考慮してください。

$ curl -i http://myapi.com/people
HTTP/1.1 200 OK

応答ペイロードは以下のとおりである.

{
    "_items": [
        {
            "firstname": "Mark",
            "lastname": "Green",
            "born": "Sat, 23 Feb 1985 12:00:00 GMT",
            "role": ["copy", "author"],
            "location": {"city": "New York", "address": "4925 Lacross Road"},
            "_id": "50bf198338345b1c604faf31",
            "_updated": "Wed, 05 Dec 2012 09:53:07 GMT",
            "_created": "Wed, 05 Dec 2012 09:53:07 GMT",
            "_etag": "ec5e8200b8fa0596afe9ca71a87f23e71ca30e2d",
            "_links": {
                "self": {"href": "people/50bf198338345b1c604faf31", "title": "person"},
            },
        },
        ...
    ],
    "_meta": {
        "max_results": 25,
        "total": 70,
        "page": 1
    },
    "_links": {
        "self": {"href": "people", "title": "people"},
        "parent": {"href": "/", "title": "home"}
    }
}

♪the _items リストは要求されたデータを含む.自分のフィールドに加えて、各アイテムは、いくつかの重要な追加フィールドを提供する:

フィールド.フィールド

説明する.

_created

プロジェクト作成日。

_updated

プロジェクトは前回の更新時間です。

_etag

Etagは,制御と条件要求を同時に行うために用いられる.

_id

唯一の項鍵も,個々の項終端ノードにアクセスするために必要な鍵である.

これらの追加フィールドは、APIによって自動的に処理される(クライアントは、リソースを追加/編集する際にそれらを提供する必要がない)。

♪the _meta フィールドはページデータを提供し,以下の場合にのみ出現する. ページを分ける. 有効になりました(デフォルトの場合)。それは... _links リスト提供 HATEOAS 指令する。

サブ資源.

エンドポイントはサブリソースをサポートしていますので、以下のことができます。 people/<contact_id>/invoices それがそうです。設置している url ルールは、このようなエンドポイントに対して、正規表現を使用してフィールド名を割り当てることができます。

invoices = {
    'url': 'people/<regex("[a-f0-9]{24}"):contact_id>/invoices'
    ...

そして,以下の端点を取得する.

people/51f63e0838345b6dcd7eabff/invoices

以下のように下位データベースに問合せが生じる.

{'contact_id': '51f63e0838345b6dcd7eabff'}

そしてこれです

people/51f63e0838345b6dcd7eabff/invoices?where={"number": 10}

以下のようにクエリされる.

{'contact_id': '51f63e0838345b6dcd7eabff', "number": 10}

APIを設計する際には、サブリソースを借りなくてもよい場合が多いことに注意されたい。上記の例では、1つを簡単に開示することにより invoices クライアントが以下のように問い合わせることができる終端ノード:

invoices?where={"contact_id": 51f63e0838345b6dcd7eabff}

あるいは…。

invoices?where={"contact_id": 51f63e0838345b6dcd7eabff, "number": 10}

これは設計選択であることが大きいが,単一の文書サイトを有効にする際に性能に影響を与える可能性があることを覚えておいてください.これは合法的なGET要求です

people/<contact_id>/invoices/<invoice_id>

これにより、データベース上で2つのフィールドが検索される。これは理想的でもなく本当に必要なものでもありません <invoice_id> ユニークな分野です対照的に、単純なリソースエンドポイントを有する場合、文書検索は単一のフィールド上で行われる:

invoices/<invoice_id>

サブリソースをサポートするサイトは DELETE 運営部。A DELETE 以下の端末に接続する:

people/51f63e0838345b6dcd7eabff/invoices

これにより、以下のクエリに一致するすべての文書が削除されます。

{'contact_id': '51f63e0838345b6dcd7eabff'}

したがって,子資源サイトに対しては,サイトの意味を満たす文書のみを削除する.これは標準的な行為とは異なり,集合の端点に対する削除操作は集合中のすべての文書を削除することになる.

もう一つ例を挙げましょうA DELETE 次の項目の最終ノードまで:

people/51f63e0838345b6dcd7eabff/invoices/1

これにより、以下のクエリ一致のすべての文書が削除されます。

{'contact_id': '51f63e0838345b6dcd7eabff', "<invoice_id>": 1}

この行為は典型的な木構造をサポートしており,その中で資源のID自体がマスタ鍵であるとは限らない.

カスタマイズ可能な複数のプロジェクトサイト

資源は単一の終端ノードを公開することができるか、または公開することができない。API消費者はアクセスできます people そして、 people/<ObjectId> そして people/Doe しかし限定されています /works それは.プロジェクト終端ノードへのアクセス権限を付与すると、正規表現で定義された2つのルックアップを最大2つ定義することができます。最初はメインエンドポイントであり、データベースのマスタキー構造と一致します(すなわち ObjectId MongoDBデータベースにある).

$ curl -i http://myapi.com/people/521d6840c437dc0002d1203c
HTTP/1.1 200 OK
Etag: 28995829ee85d69c4c18d597a0f68ae606a266cc
Last-Modified: Wed, 21 Nov 2012 16:04:56 GMT
...

2つ目はオプションで読み取り専用であり、イヴがどうしても第1の適合項目のみを検索するので、一意の値を有するフィールドに一致するであろう。

$ curl -i http://myapi.com/people/Doe
HTTP/1.1 200 OK
Etag: 28995829ee85d69c4c18d597a0f68ae606a266cc
Last-Modified: Wed, 21 Nov 2012 16:04:56 GMT
...

我々がアクセスするのは同じ項であるため,この2つの場合,応答負荷は以下のようになる.

{
    "firstname": "John",
    "lastname": "Doe",
    "born": "Thu, 27 Aug 1970 14:37:13 GMT",
    "role": ["author"],
    "location": {"city": "Auburn", "address": "422 South Gay Street"},
    "_id": "50acfba938345b0978fccad7"
    "_updated": "Wed, 21 Nov 2012 16:04:56 GMT",
    "_created": "Wed, 21 Nov 2012 16:04:56 GMT",
    "_etag": "28995829ee85d69c4c18d597a0f68ae606a266cc",
    "_links": {
        "self": {"href": "people/50acfba938345b0978fccad7", "title": "person"},
        "parent": {"href": "/", "title": "home"},
        "collection": {"href": "people", "title": "people"}
    }
}

ご覧のようにプロジェクトのサイトは自分の HATEOAS 指令する。

ご注意ください

REST原則によれば、リソース項目は一意の識別子のみを持たなければならない。EVEは、各アイテムにデフォルトエンドポイントを提供することを主張しています。副次的なサイトを追加することは慎重に考慮すべき決定だ。

上の例を考えてみましょうなくても people/<lastname> エンドポイント,クライアントはつねに姓ごとにリソースサイトを問い合わせることで人員を検索することができる: people/?where={{"lastname": "Doe"}} それがそうです。実際,全体例はfubarであり,複数人が同じ姓を使用している可能性があるが,その意味を理解することができる.

濾過除去.

資源終端ノードは,利用者が複数の文書を検索することを許可する.クエリ文字列をサポートし、フィルタリングとソートを可能にします。ネイティブMongoクエリとPython条件式を同時にサポートします。

ここでは全ての文書やこれらの文書を提供することを要求しています lastname 値が. Doe

http://myapi.com/people?where={"lastname": "Doe"}

使用 curl あなたはそうします

$ curl -i -g http://myapi.com/people?where={%22lastname%22:%20%22Doe%22}
HTTP/1.1 200 OK

埋め込まれた文書フィールドは、フィルタリングされることができる:

http://myapi.com/people?where={"location.city": "San Francisco"}

日付フィールドも簡単に調べられます:

http://myapi.com/people?where={"born": {"$gte":"Wed, 25 Feb 1987 17:00:00 GMT"}}

期日値はRFC 1123に適合しなければならない。異なるフォーマットが必要でしたら、変更できます DATE_FORMAT セット。

一般的にはほとんどの人は MongoDB queries “仕事だけ”。もしあなたが必要なら、 MONGO_QUERY_BLACKLIST あなたが不要なオペレータをブラックリストに入れることを許可します。

ネイティブPython文法の動作原理は以下の通りです。

$ curl -i http://myapi.com/people?where=lastname=="Doe"
HTTP/1.1 200 OK

これらの演算子は入れ子と組合せであるにもかかわらず,これらの演算子は条件演算子と論理和/または演算子の使用を許す.

デフォルトでは、すべての帳票フィールド上のフィルタが有効状態にあります。しかしながら、API保守担当者は、それらをすべて無効にすること、および/または許可されたAPIをホワイトリストに登録することを選択することができる(参照 ALLOWED_FILTERS はい。 全体構成. )。非インデックスフィールドへの問合せがDB DoS攻撃を捕捉したり心配したりする必要があれば,許可されたフィルタをホワイトリストに登録することが可能である.

また、リソースのアーキテクチャに従って入力されたフィルタを検証し、任意のフィルタが無効なときにフィルタの適用を拒否することを選択することができます。方法は使用です。 VALIDATE_FILTERING システム設定(参照 全体構成.

美輪美穂の印刷

名前のクエリーパラメータを指定することで、応答をきれいに印刷することができます pretty

$ curl -i http://myapi.com/people?pretty
HTTP/1.1 200 OK

{
    "_items": [
        {
            "_updated": "Tue, 19 Apr 2016 08:19:00 GMT",
            "firstname": "John",
            "lastname": "Doe",
            "born": "Thu, 27 Aug 1970 14:37:13 GMT",
            "role": [
                "author"
            ],
            "location": {
                "city": "Auburn",
                "address": "422 South Gay Street"
            },
            "_links": {
                "self": {
                    "href": "people/5715e9f438345b3510d27eb8",
                    "title": "person"
                }
            },
            "_created": "Tue, 19 Apr 2016 08:19:00 GMT",
            "_id": "5715e9f438345b3510d27eb8",
            "_etag": "86dc6b45fe7e2f41f1ca53a0e8fda81224229799"
        },
        ...
    ]
}

選別.選別

ランク付けもサポートされています。

$ curl -i http://myapi.com/people?sort=city,-lastname
HTTP/1.1 200 OK

まず都市ごとに,姓(降順)にソートされた文書に戻る.ご覧のように、フィールドの順序を逆にする必要がある場合は、フィールド名の前に減号を加えればよい。

MongoDBデータ層はネイティブMongoDB文法もサポートしています:

http://myapi.com/people?sort=[("lastname", -1)]

これは以下のことを意味する curl お願い:

$ curl -i http://myapi.com/people?sort=[(%22lastname%22,%20-1)]
HTTP/1.1 200 OK

姓の降順にソートされた文書を返す.

デフォルトで順序付けを有効にし、グローバルおよび/またはリソースレベルで順序付けを無効にすることができます(参照 SORTING はい。 全体構成. そして sorting はい。 ドメイン構成 )。各APIエンドポイントにデフォルトの順序付けを設定することもできます(参照 default_sort はい。 ドメイン構成 )。

ご注意ください

フィールド名と値は、常に二重引用符を使用して囲まれる。単引用符の使用は 400 Bad Request 返事をする。

HATEOAS

ハイパーメディアはアプリケーション状態のエンジンとして (HATEOAS) デフォルトで有効です。各GET応答には1つが含まれています _links 一節です。リンクはそれに関するものを提供します relation アクセスされた資源に対して title それがそうです。そして、クライアントは、関係やタイトルを使用してそのUIを動的に更新したり、API構造を事前に知らずにAPIをナビゲートしたりすることができる。例:

{
    "_links": {
        "self": {
            "href": "people",
            "title": "people"
        },
        "parent": {
            "href": "/",
            "title": "home"
        },
        "next": {
            "href": "people?page=2",
            "title": "next page"
        },
        "last": {
            "href": "people?page=10",
            "title": "last page"
        }
    }
}

APIホームページ(API入口ポイント)へのGET要求は、アクセス可能なリソースを指すリンクリストと共に提供される。そこから、どのクライアントも、各応答によって提供されるリンクに従うだけでAPIをナビゲートすることができる。

HATEOASリンクは常にAPI入口点に対して存在するので、あなたのAPIホームページが位置していれば examples.com/api/v1 vt.的 self 以上の例のリンクは 端点は位置しています examples.com/api/v1/people それがそうです。

ご注意ください next そして、 previous そして、 last そして related プロジェクトは適切な時にのみ含まれるだろう。

HATEOASを無効にする

HATEOASは、APIおよび/またはリソースレベルで無効にすることができる。なぜHATEOASを消したの?クライアント·アプリケーションがこの機能を使用しないことを知っている場合、帯域幅とパフォーマンスを同時に節約することを望む場合があります。

レンダリングする.

要求に応じて、EVE応答はJSON(デフォルト)またはXMLとして自動的に提示されます。 Accept ヘディングです。入局文書(内挿および編集用)はJSON形式である。

$ curl -H "Accept: application/xml" -i http://myapi.com
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
...
<resource>
    <link rel="child" href="people" title="people" />
    <link rel="child" href="works" title="works" />
</resource>

編集によりデフォルトレンダラーを変更することができます RENDERERS ファイル中の値を設定します。

RENDERERS = [
    'eve.render.JSONRenderer',
    'eve.render.XMLRenderer'
]

サブクラス化により自分のレンダラーを作成することができます eve.render.Renderer それがそうです。各レンダラは有効に設定する必要があります mime 属性とHAVE .render() 方法は既に実現された.少なくとも1つのレンダラーを常に有効にしなければならないことに注意してください。

条件付き請求

すべてのリソース表示は前回更新された情報を提供します (Last-Modified )と、表示自体で計算されたハッシュ値 (ETag )。これらのヘッダはクライアントが使用することを可能にする If-Modified-Since タイトル:

$ curl -H "If-Modified-Since: Wed, 05 Dec 2012 09:53:07 GMT" -i http://myapi.com/people/521d6840c437dc0002d1203c
HTTP/1.1 200 OK

あるいは…。 If-None-Match タイトル:

$ curl -H "If-None-Match: 1234567890123456789012345678901234567890" -i http://myapi.com/people/521d6840c437dc0002d1203c
HTTP/1.1 200 OK

データの完全性と同時制御

API応答は1つを含む ETag ヘッダはまた、適切な同時制御を可能にする。Vbl.一種 ETag サーバ上のリソースの現在の状態を表すハッシュ値である.消費者は編集を許可しません (PATCH あるいは…。 PUT )または削除 (DELETE )最新のリソースを提供しない限り ETag 彼らが編集しようとしている資源ですこれは古いバージョンでプロジェクトをカバーすることを防ぐことができる。

以下のワークフローを考慮してください。

$ curl -H "Content-Type: application/json" -X PATCH -i http://myapi.com/people/521d6840c437dc0002d1203c -d '{"firstname": "ronald"}'
HTTP/1.1 428 PRECONDITION REQUIRED

私たちは編集しようとしました (PATCH )でも提供されていません ETag そこで私たちは 428 PRECONDITION REQUIRED 下がって。もう一度やってみましょう

$ curl -H "If-Match: 1234567890123456789012345678901234567890" -H "Content-Type: application/json" -X PATCH -i http://myapi.com/people/521d6840c437dc0002d1203c -d '{"firstname": "ronald"}'
HTTP/1.1 412 PRECONDITION FAILED

今回は何か問題がありましたか。私たちは強制的な If-Match ヘッダですがその値は ETag 現在サーバに格納されている項の表示から計算を行うため,1つを得る. 412 PRECONDITION FAILED それがそうです。もう一回!

$ curl -H "If-Match: 80b81f314712932a4d4ea75ab0b76a4eea613012" -H "Content-Type: application/json" -X PATCH -i http://myapi.com/people/50adfa4038345b1049c88a37 -d '{"firstname": "ronald"}'
HTTP/1.1 200 OK

やっと来ました!応答ペイロードは以下のとおりである.

{
    "_status": "OK",
    "_updated": "Fri, 23 Nov 2012 08:11:19 GMT",
    "_id": "50adfa4038345b1049c88a37",
    "_etag": "372fbbebf54dfe61742556f17a8461ca9a6f5a11"
    "_links": {"self": "..."}
}

今回はパッチをインストールし、サーバは新しいものを返しました ETag それがそうです。また新しいのを受け取ります _updated この値は最終的には次のようなものを実行することができます conditional requests それがそうです。

同時制御はすべての編集方法に適用される: PATCH (編集)、 PUT (置き換え)、 DELETE (削除)。

同時制御を無効にする

もしあなたの用例が必要なら、同時制御を完全に無効にすることを選択することができます。Etagマッチングチェックの設定により、Etagマッチングチェックを無効にすることができます IF_MATCH 構成変数は False (会いましょう) 全体構成. )。同時制御を無効にした場合,Etagは何の応答も提供しない.この機能を無効にする際には、古いバージョンの文書を置き換える危険性があるので、APIを効率的に開くことができるので、特に気をつけなければならない。あるいは、以下の場合、クライアントは、Etagマッチングチェックをオプションに設定することができる。 ENFORCE_IF_MATCH 障害があります。同時検査強制を無効にする場合 If-Match ヘッダは条件要求として処理され、ありません If-Match タイトルは条件として扱われない.

一括挿入

お客様は挿入のために単一の文書を提出することができます:

$ curl -d '{"firstname": "barack", "lastname": "obama"}' -H 'Content-Type: application/json' http://myapi.com/people
HTTP/1.1 201 OK

本例では、応答ペイロードは、関連文書メタデータのみを含む。

{
    "_status": "OK",
    "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
    "_id": "50ae43339fa12500024def5b",
    "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c"
    "_links": {"self": {"href": "people/50ae43339fa12500024def5b", "title": "person"}}
}

一人になる 201 Created POST要求の後に戻ると Location ヘッダは応答にも含まれる.その値は新しい文書のURIである.

ループバックの数を減らすために、クライアントはまた、1つの要求に複数の文書を提出する可能性がある。それに必要なのは、JSONリストに文書を含めることです。

$ curl -d '[{"firstname": "barack", "lastname": "obama"}, {"firstname": "mitt", "lastname": "romney"}]' -H 'Content-Type: application/json' http://myapi.com/people
HTTP/1.1 201 OK

応答は、各文書の状態が含まれるリスト自体である。

{
    "_status": "OK",
    "_items": [
        {
            "_status": "OK",
            "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
            "_id": "50ae43339fa12500024def5b",
            "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c"
            "_links": {"self": {"href": "people/50ae43339fa12500024def5b", "title": "person"}}
        },
        {
            "_status": "OK",
            "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
            "_id": "50ae43339fa12500024def5c",
            "_etag": "62d356f623c7d9dc864ffa5facc47dced4ba6907"
            "_links": {"self": {"href": "people/50ae43339fa12500024def5c", "title": "person"}}
        }
    ]
}

複数の文書を提出する場合,APIはMongoDBを利用する. 大容量挿入 機能は、1つの要求のみがクライアントから遠隔APIに送信されるだけでなく、APIサーバとデータベースとの間で単一のループバックが実行されることを意味する。

何度も挿入に成功した場合は、覚えておいてください Location Headerは、最初に作成された文書のURIのみを返します。

データ検証

データ検証は箱を開けてすぐに使用する.あなたの構成には、API管理の各リソースのアーキテクチャ定義が含まれています。挿入/更新するAPIに送信されたデータはアーキテクチャに従って検証され,検証が通過した場合にのみリソースが更新される.

$ curl -d '[{"firstname": "bill", "lastname": "clinton"}, {"firstname": "mitt", "lastname": "romney"}]' -H 'Content-Type: application/json' http://myapi.com/people
HTTP/1.1 201 OK

応答は、要求内に提供される各項目の成功/エラー状態を含む:

{
    "_status": "ERR",
    "_error": "Some documents contains errors",
    "_items": [
        {
            "_status": "ERR",
            "_issues": {"lastname": "value 'clinton' not unique"}
        },
        {
            "_status": "OK",
        }
    ]
]

上記の例では、第1の文書は検証されていないため、要求全体が拒否される。

すべての文書が検証されて正しく挿入された場合,応答状態は 201 Created それがそうです。いずれの文書も検証されていない場合、応答状態は 422 Unprocessable Entity 定義された他のエラーコードでも VALIDATION_ERROR_STATUS 配置します。

より多くの情報については、参照されたい データ検証 それがそうです。

拡張可能なデータ検証

データ検証は Cerberus 検証システムは、したがって拡張可能なので、特定の用例に応じて調整することができます。APIはあるフィールド値の奇数しか受け入れられないと仮定します。これを検証するために検証クラスを拡張することができます。代替的に、付加価値税フィールドがあなたの国/地域の付加価値税アルゴリズムと実際に一致することを保証したいと仮定します。あなたもこれをすることができます。実際,EveのMongoDBデータ層自体は実現されている. unique アーキテクチャフィールド制約。より多くの情報については、参照されたい データ検証 それがそうです。

文書を編集する(パッチ)

クライアントは使用可能です PATCH 方法、そして PUT それに取って代わることになります PATCH フィールドを削除することはできませんが、その値しか更新できません。

以下のアーキテクチャを考慮してください。

'entity': {
    'name': {
        'type': 'string',
        'required': True
    },
    'contact': {
        'type': 'dict',
        'required': True,
        'schema': {
            'phone': {
                'type': 'string',
                'required': False,
                'default': '1234567890'
            },
            'email': {
                'type': 'string',
                'required': False,
                'default': 'abc@efg.com'
            },
        }
    }
}

2つの記号: {{contact: {{email: 'an email'}}}} そして {{contact.email: 'an email'}} 更新に利用可能 email フィールドの中の contact サブドキュメントです。

切記する. PATCH フィールドを削除することはできませんが、既存の値しか更新できません。また、デフォルトの場合、 PATCH デフォルト値の欠落本文フィールドは、アーキテクチャで標準化されます。上のアーキテクチャを考えてください。もしあなたの PATCH 身体はこうです

{'contact.email': 'xyz@gmail.com'}

この文書を目指しています

{
  'name': 'test account',
  'contact': {'email': '123@yahoo.com', 'phone': '9876543210'}
}

更新後の文書は以下のようになる.

{
  'name': 'test account',
  'contact': {
    'email': 'xyz@gmail.com',
    'phone': '1234567890'
  }
}

つまり、 contact.phone デフォルト値にリセットされています。これは私たちが望む行動ではないかもしれない。これを変更するには、設定することができます normalize_on_patch (または) NORMALIZE_ON_PATCH 全局に至る False それがそうです。いま,更新後の文書は以下のようになる.

{
  'name': 'test account',
  'contact': {
    'email': '123@yahoo.com',
    'phone': '9876543210'
  }
}

リソースレベルキャッシュ制御

グローバルおよび個々のキャッシュ制御命令を各リソースに設定することができます。

$ curl -i http://myapi
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 131
Cache-Control: max-age=20
Expires: Tue, 22 Jan 2013 09:34:34 GMT
Server: Eve/0.0.3 Werkzeug/0.8.3 Python/2.7.3
Date: Tue, 22 Jan 2013 09:34:14 GMT

上の応答にはこの2つの場合があります Cache-Control そして Expires タイトル。これは,キャッシュを有効にする利用者が真に必要な場合にのみ資源集約型要求を実行するため,サーバ上の負荷を最小限に抑えることができる.

APIバージョン制御

私はAPIバージョンの制御があまり好きではありません。クライアントはAPI更新を透過的に扱うことができ,特にEveをサポートするAPIがサポートされた後には十分に知的であるべきであると考えられる. HATEOAS. バージョン制御が必要な場合、バージョン間には、キャッシュ、URI、モード、検証など、多くの異なるものがある可能性があるので、異なるAPIバージョンは独立したインスタンスであるべきである。URIバージョン制御(http://api.example.com/v 1/...)支持しています。

文書バージョン制御

EVEは文書の自動バージョン制御をサポートしている.デフォルトの場合、この設定はオフ状態にありますが、グローバルに有効にしたり、各リソースのために個別に構成したりすることができます。有効になった後、イヴは文書の変更を自動的に追跡してフィールドを追加し始めます _version そして _latest_version 文書を検索する際に.

舞台裏では,イヴはEveが定義した各主要資源の集合に平行な影の集合に文書バージョンを格納する.通常のPOST、PUT、PATCH動作中に、新しい文書バージョンが自動的にこのセットに追加されます。文書バージョンへのアクセスを提供する項目を取得する際に、特別な新しいクエリーパラメータを利用することができる。特定のバージョンへのアクセスを使用する ?version=VERSION すべてのバージョンにアクセス ?version=all すべてのバージョンにアクセスする差異を使用します ?version=diffs それがそうです。集合問合せ機能(例えば、投影、ページ分け、順序付け)を使用する all そして diff 機能しないランキングを除いて diff それがそうです。

バージョン制御を有効にする際に、いくつかの非標準シーンが予期しない結果を生じる可能性があることに注意されたい。特に,EVEが生成したAPI以外で集合を修正する場合には,文書履歴を保存しない.またもしいつでも VERSION フィールドがメインファイルから除去され(バージョン制御が開いている場合、APIによってこの動作が実行できない場合)、後続の書き込みは再初期化される。 VERSION 番号は VERSION =1.このとき,複数のバージョンの文書は同じバージョン番号を持つ.通常の状況では VERSIONING どの新しいセットについても、以前にバージョン制御が有効にされていなかった既存のセットについても、気兼ねなく有効にすることができる。

また,文書バージョン特有のキャッシュコーナーサイズもある.特定の文書バージョンには _latest_version フィールドでは、このフィールドの値は、新しいドキュメントバージョンを作成する際に変更されます。それを説明するために、イブは時間を決めました _latest_version (主文書に対する前回更新されたタイムスタンプ)を変更し、この値を用いてパディングを行う Last-Modified 見出しと検査 If-Modified-Since 特定の文書バージョンクエリの条件キャッシュ検証器。これは、バージョンの最後の更新フィールドのタイムスタンプとは異なることに留意されたい。文書バージョンのEtagは以下の場合は変更されません _latest_version しかし、状況は変化した。これは2つの角点の状況を招いた。まずイブは顧客がいるかどうかを確認できないからです _latest_version Etagのみから更新されており、このクエリは使用のみとなっております If-None-Match 旧文書バージョンのキャッシュ検証では,そのキャッシュはつねに無効となる.第二に、複数の新しいバージョンを作成しながら取得およびキャッシュされたバージョンは、不正確な情報を受信する可能性がある Not Modified それに伴う返事 GET 以下の理由によるクエリ Last-Modified 値の解像度は1秒であるが,静的Etag値は変更の指示を提供しない.いずれの場合も不可能な場合であるが,毎秒複数回の編集が期待されるアプリケーションは,古いコンテンツを残す可能性を考慮すべきである. _latest_version データです。

詳細については、和を参照されたい 全体構成. そして ドメイン構成 それがそうです。

認証

カスタマイズ可能な基本認証(RFC−2617)、トークンベースの認証、およびHMACベースの認証がサポートされる。OAuth 2は簡単に統合できます。API全体をロックすることもできますし、一部のエンドポイントのみをロックすることもできます。また、許可されたユーザへの編集、挿入、および削除を制限しながら、読み出し専用アクセスを開くことができるようにCRUDコマンドを制限することができます。役割ベースのアクセス制御もサポートされています。より多くの情報については、参照されたい 認証と権限 それがそうです。

CORSドメイン間資源共有

EVEによるAPIは,Webページに含まれるJavaScriptでアクセス可能である.デフォルトでは無効になります CORS ウェブページがREST APIを使用することを可能にすることは、一般に、多くのブラウザ“同じドメイン”セキュリティポリシーによって制限される。♪the X_DOMAINS 設定許可は、どのドメインがCORS要求を実行することを許可するかを指定する。正規表現リストは X_DOMAINS_RE これは,ダイナミックレンジを持つサブドメインのサイトに非常に有用である.正しいアンカーおよび変換正規表現、例えば、正しいアンカーおよび変換正規表現を保証する X_DOMAINS_RE = ['^http://sub-\d{{3}}\.example\.com$'] それがそうです。

JSONPサポート

一般に、CORSを有効にすることができる場合、あなたは本当にJSONPを追加したいわけではありません。

ある人たちはJSONPに対していくつかの批判をした。ドメイン間資源共有(CORS)は、異なるドメインにおけるサーバからデータを取得する比較的新しい方法であり、いくつかの批判を解決する。すべての現代ブラウザは現在CORSをサポートしており、ブラウザ横断代替案となっています。 (source. )

しかし、場合によっては、あなたはJSONPが必要であり、例えば、レガシーソフトウェアをサポートしなければならない場合(IE 6は誰かいますか?)

EVEでJSONPを有効にするには、設定するだけです JSONP_ARGUMENT それがそうです。そしてどのようなものでも JSONP_ARGUMENT パラメータ値でパッケージされた応答が返される。例えば設定すれば JSON_ARGUMENT = 'callback'

$ curl -i http://localhost:5000/?callback=hello
hello(<JSON here>)

お願いはありません callback パラメータはJSONPなしで送られる.

デフォルトの場合は読むだけです

もしあなたが必要なのがただの読み取り専用APIであれば、数分以内に起動して実行することができます。

デフォルト値と空にすることができる値

フィールドは、デフォルト値と、空であってもよいタイプとを有することができる。POST(CREATE)要求を処理する際には、欠落フィールドに構成されたデフォルト値が割り当てられる。見 default そして nullable キーワード入力 構造定義 より多くの情報を得ることができます

事前定義されたデータベースフィルタ

リソースエンドポイントは、所定のフィルタに一致する文書のみを公開(および更新)する。これにより、複数のリソースエンドポイントが同一のデータベースセットをシームレスに照準することができる。典型的な用例は仮定するだろう people 対象者が使用しているデータベース上の /admins そして /users APIエンドポイント。

推算する

この機能は、セットおよび文書の動的ビューを作成することができ、またはより正確には、“投影”を使用して、どのフィールドに戻るべきか、または返すべきでないかを決定することを可能にする。言い換えれば、投影は条件クエリであり、クライアントは、APIがどのフィールドを返すべきかを指定する。

$ curl -i -G http://myapi.com/people --data-urlencode 'projection={"lastname": 1, "born": 1}'
HTTP/1.1 200 OK

上のクエリは戻るだけです そして born ‘People’リソース内のすべての利用可能なフィールドにあります。フィールドを除外することもできます。

$ curl -i -G http://myapi.com/people --data-urlencode 'projection={"born": 0}'
HTTP/1.1 200 OK

上のコードはすべてのフィールドに戻りますが born それがそうです。ID_FIELD、DATE_CREATED、DATE_UPDATEDなどのキーフィールドは依然としてペイロードに含まれることに注意されたい。Mongoを含むいくつかのデータベースエンジンは包括的および排他的選択の混合使用を許可していないことを覚えておいてください。

組み込み資源序列化

文書フィールドが別のリソース内の文書を参照している場合、クライアントは、参照文書を要求された文書に埋め込むことを要求することができる。

クライアントは,問合せパラメータを介して要求に応じて文書埋め込みを活性化することができる.もしあなたが1つ持っているとしたら emails 資源配置は以下のとおりである.

 DOMAIN = {
     'emails': {
         'schema': {
             'author': {
                 'type': 'objectid',
                 'data_relation': {
                     'resource': 'users',
                     'field': '_id',
                     'embeddable': True
                 },
             },
             'subject': {'type': 'string'},
             'body': {'type': 'string'},
         }
     }

Aは以下のとおりである. /emails?embedded={{"author":1}} 同じ要求は含まれていないが、完全に埋め込まれたユーザ文書が返される。 embedded パラメータはユーザのみに戻ります ObjectId それがそうです。組込み資源の直列化は資源でも項でも利用可能である. (/emails/<id>/?embedded={{"author":1}} )エンドポイント。

(設定によって)グローバルレベルで埋め込みを有効または無効にすることができる EMBEDDING いずれにしても True あるいは…。 False )とリソースレベル(切り替えにより) embedding 値)。他にもあるのは embeddable 値は明示的に設定されている True 引用された文書の埋め込みを許可する.

埋め込みは文書の特定のバージョンのdata_relationshipにも適用されるが,パターンが少し異なるように見える.特定のバージョンのdata_relationshipを有効にするには、追加してください 'version': True DATA_RELATIONブロックに行きます。変更する必要があります type 至る dict 追加します schema 定義を以下に示す.

 DOMAIN = {
     'emails': {
         'schema': {
             'author': {
                 'type': 'dict',
                 'schema': {
                     '_id': {'type': 'objectid'},
                     '_version': {'type': 'integer'}
                 },
                 'data_relation': {
                     'resource': 'users',
                     'field': '_id',
                     'embeddable': True,
                     'version': True,
                 },
             },
             'subject': {'type': 'string'},
             'body': {'type': 'string'},
         }
     }

ご覧のように 'version': True DATA_RELATIONフィールドの期待値をフィールド名付き辞書に変更する data_relation['field'] そして VERSION それがそうです。使用 'field': '_id' 上のdata_relationship定義では, VERSION = '_version' EVE構成では、このシーンにおけるdata_relation値は、フィールドを有する辞書となる _id そして _version それがそうです。

所定の資源序列化

いくつかのフィールドはまた、所定のリソース直列化のために選択されてもよい。リストされたフィールドが埋め込み可能であり、それらが実際に他のリソース内の文書を参照し(リソースのための埋め込みが有効にされている)場合、デフォルトで参照文書が埋め込まれる。クライアントは、デフォルトで埋め込まれたフィールドから終了を選択することができる:

$ curl -i http://example.com/people/?embedded={"author": 0}
HTTP/1.1 200 OK

局限性

現在,どのサブファイル(入れ子辞書とリスト)に位置する参照により文書を埋め込むことを支援している.例えば、クエリ /invoices/?embedded={{"user.friends":1}} 1つの包含に戻ります user そして彼が持っているのは friends 埋め込まれていますが user サブ文書であり friends 引用リスト(辞書リスト,入れ子辞書などであってもよい)である.この機能はGET要求の直列化に関するものである.埋め込み文書のPOST,PUTまたはPATCHはサポートされていない.

デフォルトで文書埋め込みを有効にします。

ご注意ください

MongoDBに対して,組込み資源の直列化を扱うのは 文書引用 (リンク文書)は、 埋め込み文書. イヴの支持も得ました(参照 MongoDB Data Model Design )。組み込みリソースの直列化は良い特性であり、クライアントのデータモデルの正規化を本当に助けることができます。しかし,それを有効にするかどうかを決定する際には,特にデフォルトの場合,探すための組込み資源ごとにデータベース探索が必要であり,性能の問題を招きやすいことを覚えておいてください.

ソフト削除.

EVEは、削除された文書をデータベースに格納し続け、復元することができるが、API要求の削除項目としてもよいオプションの“ソフト削除”モードを提供する。ソフト削除はデフォルトでは無効状態ですが、ご利用いただけます SOFT_DELETE 構成設定、またはドメイン構成を使用してリソースレベルで個別に構成される soft_delete セット。見 全体構成. そして ドメイン構成 ソフト削除の有効化と構成の詳細については、以下の操作を実行してください。

ソフト削除を有効にする場合、追加 on_delete_resource_originals そして on_delete_resource_originals_<resource_name> イベントは,削除された文書と削除されていない文書を同時に受信する. originals パラメータ(参照) 事件とリンクする. )。

行い

ソフト削除を有効にする場合、単一の項目およびリソースの削除要求に対する応答は、従来の“ハード”削除と同様である。しかし,舞台裏では,イヴは削除された項をデータベースから削除するのではなく,使用している _deleted メタフィールドは、 true それがそうです。(その会社の名称 _deleted フィールドは構成可能である.見 全体構成. ()ソフト削除を有効にする際に発行されるすべての要求は _deleted 現場です。

♪the _deleted フィールドは自動的に追加され初期化される false ソフト削除を有効にする際に作成されたすべての文書について。ソフト削除を有効にする前に作成された文書ですので、定義しません _deleted データベースのフィールドにはまだ含まれています _deleted: false API応答データには,EVEが応答を構築する際に追加される.これらの文書を配置したり修復したりすると追加されます _deleted フィールドは、格納された文書に追加され、設定されます。 false それがそうです。

ソフト削除文書取得要求に対する応答は,紛失や“硬い”文書削除に対する応答とはやや異なる.ソフト削除ドキュメントに対するGET要求は依然として応答します 404 Not Found 状態コードであるが,応答本文にはソフト削除された文書が含まれる _deleted: true それがそうです。デフォルト設定や要求の内容にかかわらず、削除された文書に埋め込まれた文書は、応答に展開されません。 embedded パラメータを調べる。これはソフト削除された文書が 404 応答は文書が削除された場合の状態を反映し,埋め込み文書を更新する際には変更されない.

デフォルトの場合、リソースレベルGET要求は、その応答にソフト削除項目を含まない。この行為は“硬い”削除後の要求行為にマッチする.削除された項目を応答に含める必要がある場合、 show_deleted 問合せパラメータは要求に追加することができる.() show_deleted パラメータ名は構成可能である.見 全体構成. )EVEは、すべての文書に応答して、削除の有無にかかわらず、返信された文書をクライアントが解析する。 _deleted 現場です。♪the _deleted フィールドは、要求中に明示的なフィルタリングを行うこともでき、使用のみを許可することができる ?where={{"_deleted": true}} 調べてみます。

ソフト削除はデータ層で強制的に実行され,これはアプリケーションコードが使用されることを意味する. app.data.find_one そして app.data.find 方法:ソフト削除項を自動的に抽出する。要求対象と req.show_deleted == True 明示的にスクリーニングしたり _deleted フィールドは、デフォルトのフィルタリングを上書きします。

ソフト削除を復元している項目

ソフト削除文書に対してPUTまたはパッチ要求を行うとその文書が復元され,自動的に設定される. _deleted 至る false データベースにあります。添削 _deleted フィールドは直接必要ではない(または許可されている)。たとえば,パッチ要求を用いた場合には,復元バージョンで変更するフィールドのみを指定したり,文書をそのまま復元するように空要求を行ったりする.ソフト削除文書への書き込み権限の適切な許可を得なければ要求されず,そうでなければ拒否される.

以前にソフトに削除された文書を復元する場合、最終的な一意のフィールドは、最終的には、復元された文書と、元の文書(現在復元されている)が“削除された”状態にあるときに同じフィールド値で格納されている可能性のある別の文書とで最終的に重複する可能性があることに留意されたい。これは,検証時にソフト削除された文書を無視してしまうためである. unique 新しい文書や文書を更新するルール.

版本化

ソフト削除バージョン化された文書は、その文書の新しいバージョンを作成します。 _deleted とする. true それがそうです。削除されたバージョンへのGET要求が届きます 404 Not Found 上述したように、以前のバージョンは継続して使用されるであろう 200 OK それがそうです。以下の問題への対応 ?version=diff あるいは…。 ?version=all それが他のバージョンであるように、削除されたバージョンが含まれるだろう。

データ関係.

前夜. data_relation ベリファイアは、ソフトに削除された文書を参照することを許可しない。ソフト削除文書を参照した文書の作成や更新を試みると,その文書がハードに削除されたように失敗する.ソフトに削除された文書との既存のデータ関係はデータベースに残っているが,これらの関係を組込み文書を直列化する必要がある要求は空値に解析する.同様に,これは文書をハードに削除する関係行為にマッチする.

削除された文書バージョンとのバージョン化データ関係も検証できないが,文書削除前や復元後のバージョンとの関係を許し,解析に成功し続ける.

要素を考慮する.

アプリケーションで使用後のソフト削除を無効にするには、APIが一貫していることを保証するためにデータベースメンテナンスが必要です。ソフト削除を無効にした場合、要求はこれ以上根拠や処理を行わない _deleted フィールドは、ソフトに削除された文書が今、あなたのAPI上で再起動されます。したがって,ソフト削除を無効にする際には,含まれるすべての文書を削除するためにデータ遷移を実行する必要がある. _deleted == True 削除を推奨します _deleted 以下の位置からの文書のフィールド _deleted == False それがそうです。既存のアプリケーションでソフト削除を有効にすることは安全であり、その時点から削除された文書を保持する。

事件とリンクする.

事前要求事件とリンクする.

GET/HEAD、POST、PATCH、PUT、DELETE要求を受信すると、 on_pre_<method> 1つと on_pre_<method>_<resource> 事件は起こされた。これらのイベントは、複数のコールバック関数で購読することができます。

>>> def pre_get_callback(resource, request, lookup):
...  print('A GET request on the "%s" endpoint has just been received!' % resource)

>>> def pre_contacts_get_callback(request, lookup):
...  print('A GET request on the contacts endpoint has just been received!')

>>> app = Eve()

>>> app.on_pre_GET += pre_get_callback
>>> app.on_pre_GET_contacts += pre_contacts_get_callback

>>> app.run()

コールバックは、要求されたリソース、元のリソースを受信します。 flask.request オブジェクトと現在の辞書をパラメータとして調べる(唯一の例外は on_pre_POST フック、このフックは提供されない lookup 論点)。

動的探索フィルタ

自.自.以来. lookup データ層は辞書を用いてリソース文書を検索し,開発者は検索クエリにカスタムロジックを追加するために辞書を変更することを選択することができる.

def pre_GET(resource, request, lookup):
    # only return documents that have a 'username' field.
    lookup["username"] = {'$exists': True}

app = Eve()

app.on_pre_GET += pre_GET
app.run()

実行時に辞書引きを変更する効果と適用 事前定義されたデータベースフィルタ 配置することで。しかし、静的フィルタを設定することで、フックを通過することしかできません。 on_pre_<METHOD> イベントは、より大きな柔軟性を得るために、動的フィルタを設定することに変更することができます。

依頼後事件とリンクする

GET、POST、PATCH、PUT、DELETEメソッドが実行された場合、 on_post_<method> そして on_post_<method>_<resource> 事件は起こされた。これらのイベントは、複数のコールバック関数で購読することができます。コールバックはアクセスされた元のリソースを受信します flask.request オブジェクトと応答ペイロード。

>>> def post_get_callback(resource, request, payload):
...  print('A GET on the "%s" endpoint was just performed!' % resource)

>>> def post_contacts_get_callback(request, payload):
...  print('A get on "contacts" was just performed!')

>>> app = Eve()

>>> app.on_post_GET += post_get_callback
>>> app.on_post_GET_contacts += post_contacts_get_callback

>>> app.run()

データベースイベント接続

データベースイベントリンクの動作方式は,要求イベントリンクと類似している.このようなイベントはデータベース操作の前と後に刺激される。以下は、イベントをどのように構成するかの例である。

>>> def add_signature(resource, response):
...     response['SIGNATURE'] = "A %s from eve" % resource

>>> app = Eve()
>>> app.on_fetched_item += add_signature

フラスコを使ってもいいです abort() データベース操作を中断するには、以下の操作を実行してください。

>>> from flask import abort

>>> def check_update_access(resource, updates, original):
...     abort(403)

>>> app = Eve()
>>> app.on_insert_item += check_update_access

操作がリソースおよび項の両方に利用可能である場合、リソースおよび項のイベントが励起される。各動作について、2つのイベントがトリガされる:

  • 一般的に: on_<action_name>

  • 使用リソース名: on_<action_name>_<resource_name>

利用可能な活動の概要を見てみましょう

行くぞ!

えっ?

いつ?

イベント名/メソッド署名

取得する

資源

事後に.

on_fetched_resource
def event(resource_name, response)
on_fetched_resource_<resource_name>
def event(response)

プロジェクト.

事後に.

on_fetched_item
def event(resource_name, response)
on_fetched_item_<resource_name>
def event(response)

示差.

事後に.

on_fetched_diffs
def event(resource_name, response)
on_fetched_diffs_<resource_name>
def event(response)

挿入

プロジェクト.

その前に

on_insert
def event(resource_name, items)
on_insert_<resource_name>
def event(items)

事後に.

on_inserted
def event(resource_name, items)
on_inserted_<resource_name>
def event(items)

代わる

プロジェクト.

その前に

on_replace
def event(resource_name, item, original)
on_replace_<resource_name>
def event(item, original)

事後に.

on_replaced
def event(resource_name, item, original)
on_replaced_<resource_name>
def event(item, original)

更新

プロジェクト.

その前に

on_update
def event(resource_name, updates, original)
on_update_<resource_name>
def event(updates, original)

事後に.

on_updated
def event(resource_name, updates, original)
on_updated_<resource_name>
def event(updates, original)

削除

プロジェクト.

その前に

on_delete_item
def event(resource_name, item)
on_delete_item_<resource_name>
def event(item)

事後に.

on_deleted_item
def event(resource_name, item)
on_deleted_item_<resource_name>
def event(item)

資源

その前に

on_delete_resource
def event(resource_name)
on_delete_resource_<resource_name>
def event()
on_delete_resource_originals
def event(resource_name, originals, lookup)
on_delete_resource_originals_<resource_name>
def event(originals, lookup)

事後に.

on_deleted_resource
def event(resource_name, item)
on_deleted_resource_<resource_name>
def event(item)

事件を得る

以下にFETCHイベントとその方法署名を示す.

  • on_fetched_resource(resource_name, response)

  • on_fetched_resource_<resource_name>(response)

  • on_fetched_item(resource_name, response)

  • on_fetched_item_<resource_name>(response)

  • on_fetched_diffs(resource_name, response)

  • on_fetched_diffs_<resource_name>(response)

これらは、プロジェクトがデータベースから読み取られ、クライアントに送信される直前に開始される。登録されたコールバック関数は、項をクライアントに返す前に、必要に応じて動作することができる。

>>> def before_returning_items(resource_name, response):
...  print('About to return items from "%s" ' % resource_name)

>>> def before_returning_contacts(response):
...  print('About to return contacts')

>>> def before_returning_item(resource_name, response):
...  print('About to return an item from "%s" ' % resource_name)

>>> def before_returning_contact(response):
...  print('About to return a contact')

>>> app = Eve()
>>> app.on_fetched_resource += before_returning_items
>>> app.on_fetched_resource_contacts += before_returning_contacts
>>> app.on_fetched_item += before_returning_item
>>> app.on_fetched_item_contacts += before_returning_contact

注意しなければならないのはプロジェクト取得イベントは Document Versioning 特定の文書バージョンについては ?version=5 全てが含まれています ?version=all それがそうです。すべてのバージョンにアクセスする違いを使用する ?version=diffs Diffs Fetchイベントとともにのみ使用する.なお、Diffsは、コールバックで処理すべき部分文書を返す。

挿入事件.

以下にInsertイベントとその方法署名を示す.

  • on_insert(resource_name, items)

  • on_insert_<resource_name>(items)

  • on_inserted(resource_name, items)

  • on_inserted_<resource_name>(items)

POST要求がAPIにヒットし、新しいエントリがデータベースに格納されると、以下のイベントがトリガされる。

  • on_insert すべてのリソースについて終端します

  • on_insert_<resource_name> 特定の <resource_name> 資源の最終的なノードです

コールバック関数は、新しいフィールドを任意に追加するか、または既存のフィールドを編集するために、これらのイベントにリンクすることができる。

プロジェクトを挿入すると、この2つのイベントがトリガされます。

  • on_inserted すべてのリソースについて終端します

  • on_inserted_<resource_name> 特定の <resource_name> 資源の最終的なノードです

検証ミス

パラメータとしてこれらのイベントに渡される項はリスト形式で現れる.また,検証された項目のみを送信する.

例:

>>> def before_insert(resource_name, items):
...  print('About to store items to "%s" ' % resource_name)

>>> def after_insert_contacts(items):
...  print('About to store contacts')

>>> app = Eve()
>>> app.on_insert += before_insert
>>> app.on_inserted_contacts += after_insert_contacts

交替事件.

以下にメソッド署名付きReplaceイベント:

  • on_replace(resource_name, item, original)

  • on_replace_<resource_name>(item, original)

  • on_replaced(resource_name, item, original)

  • on_replaced_<resource_name>(item, original)

PUT要求がAPIにヒットし、検証が通過後にある項目を置換しようとしている場合、以下のイベントがトリガされる。

  • on_replace どのようなリソース項目の終端ノードにも使われています

  • on_replace_<resource_name> リソースの終端を特定するためのものである.

item これから保存される新しいプロジェクトです。 original データベースに置き換えなければならない項.コールバック関数は、任意に追加または更新するために、これらのイベントにリンクすることができる item フィールド、または他の補助動作を実行する。

プロジェクトを変更すると、他の2つのイベントがトリガされます。

  • on_replaced どのようなリソース項目の終端ノードにも使われています

  • on_replaced_<resource_name> リソースの終端を特定するためのものである.

事件を更新する

以下にメソッド署名付き更新イベントを示す.

  • on_update(resource_name, updates, original)

  • on_update_<resource_name>(updates, original)

  • on_updated(resource_name, updates, original)

  • on_updated_<resource_name>(updates, original)

パッチ要求がAPIにヒットし、ある項目が検証後に更新されると、これらのイベントがトリガされる。 before プロジェクトは更新されます:

  • on_update すべてのリソースの最終ノードに使用されています

  • on_update_<resource_name> ただ当を受ける. <resource_name> 最終ノードに命中する。

ここ、ここ updates プロジェクトの更新に適用することを示しています original データベースの中で更新される項目です。コールバック関数は、これらのイベントにリンクすることができ、任意に追加または更新することができる updates あるいは,他の補助操作を実行する.

After このプロジェクトは更新されました:

  • on_updated どのような資源の終端ノードにも刺激を与える.

  • on_updated_<resource_name> ただ当を受ける. <resource_name> 最終ノードに命中する。

ご注意ください

注意してください。 last_modified そして etag ヘッダは、データベース内の項の状態と常に一致する(これらは、コールバック関数の最終的な適用の変更を反映するように更新されない)。

事件を削除する

以下にDELETEイベントとそのメソッド署名を示す.

  • on_delete_item(resource_name, item)

  • on_delete_item_<resource_name>(item)

  • on_deleted_item(resource_name, item)

  • on_deleted_item_<resource_name>(item)

  • on_delete_resource(resource_name)

  • on_delete_resource_<resource_name>()

  • on_delete_resource_originals(originals, lookup)

  • on_delete_resource_originals_<resource_name>(originals, lookup)

  • on_deleted_resource(resource_name)

  • on_deleted_resource_<resource_name>()

プロジェクト.

削除要求がプロジェクトの終端に命中すると before プロジェクトが削除されると、以下のイベントがトリガされます。

  • on_delete_item ヒットした任意の資源を要求する。

  • on_delete_item_<resource_name> 特定の <resource_name> ヒット項目の終端ノードを削除します。

After このプロジェクトは削除されました on_deleted_item(resource_name, item) そして on_deleted_item_<resource_name>(item) みんな育てられました。

item 削除する項目です。コールバック関数は、添付ファイル操作を実行するために、これらのイベントにリンクすることができる。いいえ、この点で削除操作を任意に中止することはできません(確認すべきかもしれません データ検証 または、最終的に削除コマンドを完全に無効にします)。

資源

リソース終端ノードに削除コマンド(グループ全体の一括消去を可能にする)をあえて有効にすれば、コールバック関数をリンクさせることができます on_delete_resource(resource_name) あるいは…。 on_delete_resource_<resource_name>() フックです。

  • on_delete_resource_originals 元の文書を検索した後にヒットが要求された任意のリソースについて.

  • on_delete_resource_originals_<resource_name> 特定の <resource_name> オリジナル文書を検索した後,操作がヒットした資源終端点を削除する.

発見および元のリストが与えられた場合、これら2つのイベントは、実際の削除動作の前にいくつかのトラフィックロジックを実行するために非常に有用であることに留意されたい。

事件とリンクする.

1つ以上のコールバックを統合エンドポイントに追加することもできます。♪the before_aggregation イベントは収束を実行しようとしているときに触発される.いずれの付加的なコールバック関数も,受信エンドポイント名と集約パイプラインをパラメータとする.そして、必要であれば、パイプを変更することができます。

>>> def on_aggregate(endpoint, pipeline):
...   pipeline.append({"$unwind": "$tags"})

>>> app = Eve()
>>> app.before_aggregation += on_aggregate

♪the after_aggregation イベントは収束を実行する際に呼び出される.追加のコールバック関数は、文書がクライアントに戻る前に、このイベントを使用して修正することができる。

>>> def alter_documents(endpoint, documents):
...   for document in documents:
...     document['hello'] = 'well, hello!'

>>> app = Eve()
>>> app.after_aggregation += alter_documents

集約サポートの詳細については、ご参照ください MongoDB統合フレームワーク

ご注意ください

シームレスなイベント処理機能を提供するために、イヴは Events 小包です。

速度制限.

APIの制限速度は、ユーザ/メソッドごとの制限速度をサポートしています。各HTTPメソッドのリクエスト数と時間ウィンドウを設定することができます。時間ウィンドウ内で要求制限に達した場合、APIは応答する。 429 Request limit exceeded タイマーがリセットされるまで。ユーザは、ID認証ヘッダまたは(失われた場合)クライアントIPによって識別される。レート制限を有効にする場合、適切 X-RateLimit- 各API応答は、ヘッダを提供する。速度制限が15分ごとに300要求に設定されていると仮定すると、ユーザは、単一の要求を使用してエンドポイントにヒットした後、以下の結果を得る。

X-RateLimit-Remaining: 299
X-RateLimit-Limit: 300
X-RateLimit-Reset: 1370940300

サポートされる方法(GET、POST、PATCH、DELETE)ごとに異なる制限を設定することができます。

ご注意ください

デフォルトの場合,レート制限はオフ状態であり,有効化後にRedisサーバが実行する必要がある.レート制限に関するチュートリアルが発売されます。

カスタムIDフィールド

Eveは、その標準データタイプサポートを拡張することを可能にします。はい。 カスタムIDフィールドの処理 チュートリアルでは、MongoDBのデフォルトのObjectIdsではなく、UID値を一意の文書識別子として使用する方法を見ました。

ファイル保存

メディアファイル(画像、pdfなど)アップロードすることができます media 文書フィールド。アップロードは以下のように行われます POST そして、 PUT そして PATCH いつものように、でも使います multipart/form-data 内容タイプ。

仮定してみましょう accounts エンドポイントは次のようなアーキテクチャを持つ:

accounts = {
    'name': {'type': 'string'},
    'pic': {'type': 'media'},
    ...
}

巻き毛があれば POST このように

$ curl -F "name=john" -F "pic=@profile.jpg" http://example.com/accounts

性能を最適化するためにファイルは GridFS デフォルトの場合。慣習 MediaStorage クラスを実装し、代替ストレージシステムをサポートするためにアプリケーションに渡すことができる。A FileSystemMediaStorage クラスは作成中で、すぐにEVEパッケージに含まれます。

正式な開発者案内はございませんので、ご覧いただけます MediaStorage カスタムストレージクラスの開発に興味がある場合は、参照してください。

メディアファイルをBase 64文字列としてサービスを提供

文書を要求すると,メディアファイルはBase 64文字列として返される.

 {
     '_items': [
         {
             '_updated':'Sat, 05 Apr 2014 15:52:53 GMT',
             'pic':'iVBORw0KGgoAAAANSUhEUgAAA4AAAAOACA...',
         }
     ]
     ...
}

しかしもし EXTENDED_MEDIA_INFO リストが充填されており(デフォルトでは充填されていません)、ペイロードフォーマットが異なります。このフラグは,ドライバから付加されたメタフィールドを通過することを可能にする.たとえば,MongoDBドライバを用いた場合, content_type そして、 name そして length このリストに追加し、基本ドライバから渡すことができる。

いつ? EXTENDED_MEDIA_INFO このフィールドは辞書になり、ファイル自体が格納されます file キーと他のキーは元フィールドである.このフラグを以下のように設定したとする.

EXTENDED_MEDIA_INFO = ['content_type', 'name', 'length']

出力は以下のようになる.

{
    '_items': [
        {
            '_updated':'Sat, 05 Apr 2014 15:52:53 GMT',
            'pic': {
                'file': 'iVBORw0KGgoAAAANSUhEUgAAA4AAAAOACA...',
                'content_type': 'text/plain',
                'name': 'test.txt',
                'length': 8129
            }
        }
    ]
    ...
}

MongoDBでは driver documentation それがそうです。

メディアファイル(例えば、カスタムFlaskエンドポイント)を検索する他の方法がある場合、メディアファイルをペイロードから除外するように設定することによって False ♪the RETURN_MEDIA_AS_BASE64_STRING 旗。これは以下のようなことが考えられる EXTENDED_MEDIA_INFO 全部使っています。

専用エンドポイントでメディアファイルを提供する

Base 64フィールドとして埋め込まれたファイルを返すことはデフォルトアクションですが、専用メディアエンドポイントでこれらのファイルを提供することを選択することができます。設定することで RETURN_MEDIA_AS_URL 至る True それがそうです。この機能を有効にする際には,文書フィールドは通信ファイルへのURLを含み,これらのURLはメディアエンドノードで提供される.

デフォルトのメディア·エンドポイントを変更することができます (media )を更新することにより MEDIA_BASE_URL そして MEDIA_ENDPOINT セット。Amazon S 3にカスタムファイルで画像を格納していると仮定します MediaStorage サブクラスです。メディアのサイトをこのように設定するかもしれません

# disable default behaviour
RETURN_MEDIA_AS_BASE64_STRING = False

# return media as URL instead
RETURN_MEDIA_AS_URL = True

# set up the desired media endpoint
MEDIA_BASE_URL = 'https://s3-us-west-2.amazonaws.com'
MEDIA_ENDPOINT = 'media'

設ける MEDIA_BASE_URL オプションです。値が設定されていない場合は,URLを構築する際にAPIベースアドレスを用いる. MEDIA_ENDPOINT それがそうです。

一部のメディアダウンロード

専用サイトでファイルを提供する場合,クライアントは部分ダウンロードを要求することができる.これにより、それらは、(ダウンロードを再起動することなく)最適化された一時停止/回復などの機能を提供することができる。部分ダウンロードを実行しますので、ご確認ください Range ヘッダはクライアント要求に追加される.

$ curl http://localhost/media/yourfile -i -H "Range: bytes=0-10"
HTTP/1.1 206 PARTIAL CONTENT
Date: Sun, 20 Aug 2017 14:26:42 GMT
Content-Type: audio/mp4
Content-Length: 11
Connection: keep-alive
Content-Range: bytes 0-10/23671
Last-Modified: Sat, 19 Aug 2017 03:25:36 GMT
Accept-Ranges: bytes

abcdefghilm

上のコード片には,curl要求ファイルの最初のブロックが見られる.

投影を用いたメディアファイルの処理の最適化

クライアントとAPI保守者は 推算する 応答ペイロードには、メディアフィールドの機能が含まれる/排除される。

クライアントは画像付き文書を格納していると仮定する.画像フィールドは 影像. そしてそれは media タイプです。後で、クライアントは同じ文書を検索することを望んでいるが、速度を最適化するために、画像がキャッシュされているため、画像を文書と共にダウンロードすることは望ましくない。これは、応答ペイロードからフィールドのトリミングを要求することによって達成することができる。

$ curl -i http://example.com/people/<id>?projection={"image": 0}
HTTP/1.1 200 OK

この文書は、そのすべてのフィールドと共に返されるが、 影像. 現場です。

また、設定している datasource 属性は、フィールド(の)を明示的に排除することができる media タイプであるが、他のタイプであってもよい)。

people = {
    'datasource': {
        'projection': {'image': 0}
    },
    ...
}

ここで、クライアントは、以下の要求を送信することによって、応答ペイロードに含まれる画像フィールドを明示的に要求しなければならない。

$ curl -i http://example.com/people/<id>?projection={"image": 1}
HTTP/1.1 200 OK

また見られる.

関係がある datasource セット。

メディアファイルに関する注釈は multipart/form-data

メディアファイルを multipart/form-data ファイルフィールド以外のすべてのフィールドは、ファイルフィールドを除くすべてのフィールドとみなされる strings すべての現場検証目的に用いられる.いくつかのリソースフィールドを異なるタイプ(ブール、数字、リストなど)として定義した場合、これらのフィールドの検証ルールは失敗し、リソースの提出に成功することを阻止します。

もしあなたがまだこのような状況でフィールド検証を実行したい場合、開かなければなりません。 MULTIPART_FORM_FIELDS_AS_JSON 着信フィールドをJSON符号化文字列と見なし、依然としてあなたのフィールドを検証することができるようにする。

もしあなたが本当に開けたら MULTIPART_FORM_FIELDS_AS_JSON すべてのリソースフィールドを正しく符号化されたJSON文字列として提出しなければなりません。

例えば1つは number 提出すべきは 1234 (あなたが予想していたように)。A boolean このようにしなければならないのは true (小文字にご注意ください t )。A list 文字列のタイプは ["abc", "xyz"] それがそうです。最後に1つは string これは最もつまずく可能性のあるもので、提出されなければなりません "'abc'" (二重引用符で囲まれていることに注意してください)。有効なJSON文字列が提出されているかどうか分からない場合、それが正しいことを確実にするために、http://jsonlint.com/のJSONベリファイアからそれを転送しようと試みることができます。

使用媒体リスト

メディアリストを使用する場合、これらのリストをデフォルト構成で提出することはできません。エネルギーを使う. AUTO_COLLAPSE_MULTI_KEYS そして AUTO_CREATE_LISTS このすべてを可能にすることができますこれは,中の1つのキーに複数の値を送信することを可能にする. multipart/form-data 要求し、このようにファイルリストをアップロードする。

GeoJSON

MongoDBデータ層は、 GeoJSON フォーマットです。サポートされているすべてのGeoJSONオブジェクト MongoDB 提供:

  • Point

  • Multipoint

  • LineString

  • MultiLineString

  • Polygon

  • MultiPolygon

  • GeometryCollection

これらすべてのオブジェクトはネイティブEVEデータタイプとして実現されています(参照 構造定義 )なので、それらは適切に検証されなければならない。

以下の例では拡張しました people エンドポイント、方法は location タイプフィールド Point.

people = {
    ...
    'location': {
        'type': 'point'
    },
    ...
}

連絡先とその位置を保存するのは非常に簡単です。

$ curl -d '[{"firstname": "barack", "lastname": "obama", "location": {"type":"Point","coordinates":[100.0,10.0]}}]' -H 'Content-Type: application/json'  http://127.0.0.1:5000/people
HTTP/1.1 201 OK

イヴはGeoJSONもサポートしている Feature そして FeatureCollection これらの対象は MongoDB 書類です。GeoJSON仕様許容オブジェクトは,任意の数のメンバ(名前/値対)を含む.EVE検証の実現はより厳しく,2人のメンバのみを許可する.この制限を無効にすることで ALLOW_CUSTOM_FIELDS_IN_GEOJSON 至る True それがそうです。

GeoJSONデータを調べる

一般的に、すべてのMongoDB geospatial query operators また,それに関連する幾何学的説明子をサポートする.この例では $near オペレータはある地点から1000メートルの範囲に住んでいるすべての連絡先を調べます。

?where={"location": {"$near": {"$geometry": {"type":"Point", "coordinates": [10.0, 20.0]}, "$maxDistance": 1000}}}

地理照会の詳細については、MongoDB文書を参照されたい。

内部資源.

デフォルトの場合、マスタエンドポイントの取得要求に対する応答は、すべてのリソースを含む。♪the internal_resource しかし,Settingキーワードは終端ノードを内部エンドポイントとすることを許可しており,内部データ操作にのみ利用可能である:HTTP呼び出しができず,それをスレーブとすることはできない. HATEOAS リンクします。

例えば、システムにおいて発生したすべての挿入を記録するための機構であって、監査または通知システムに使用することができる。まず私たちは internal_transaction 最終ノードはその終端ノードがタグ付けされています internal_resource

 internal_transactions = {
     'schema': {
         'entities': {
             'type': 'list',
         },
         'original_resource': {
             'type': 'string',
         },
     },
     'internal_resource': True
 }

メインサイトにアクセスして HATEOAS 有効化されていれば、私たちは受け取ることができません internal-transactions 一覧表示(HTTPで終了ノードに到着すると返されます 404 ()私たちはデータ層を使用して私たちの秘密サイトにアクセスすることができる。たぶんそうだろう。

 from eve import Eve

 def on_generic_inserted(self, resource, documents):
     if resource != 'internal_transactions':
         dt = datetime.now()
         transaction = {
             'entities':  [document['_id'] for document in documents],
             'original_resource': resource,
             config.LAST_UPDATED: dt,
             config.DATE_CREATED: dt,
         }
         app.data.insert('internal_transactions', [transaction])

 app = Eve()
 app.on_inserted += self.on_generic_inserted

 app.run()

私はこの例が最も基本的だということを認めるが、それがこれを理解させることを願う。

強化されたログ記録

多くのイベントは、デフォルトのアプリケーションレコーダによって記録することができる。基準 LogRecord attributes 以下の要求属性を用いて拡張した.

clientip

要求を実行するクライアントのIPアドレス.

url

最終クエリーパラメータを含む完全な要求URL。

method

請求方法 (POST そして、 GET (など)

これらのフィールドは、ファイルまたは任意の他のターゲットにログインする際に使用することができます。

コールバック関数は、内蔵レコーダを利用することもできる。以下の例では、アプリケーションイベントを1つのファイルに記録し、カスタム関数が呼び出されるたびにカスタムメッセージを記録する。

import logging

from eve import Eve

def log_every_get(resource, request, payload):
    # custom INFO-level message is sent to the log file
    app.logger.info('We just answered to a GET request!')

app = Eve()
app.on_post_GET += log_every_get

if __name__ == '__main__':

    # enable logging to 'app.log' file
    handler = logging.FileHandler('app.log')

    # set a custom log format, and add request
    # metadata to each log line
    handler.setFormatter(logging.Formatter(
        '%(asctime)s %(levelname)s: %(message)s '
        '[in %(filename)s:%(lineno)d] -- ip: %(clientip)s, '
        'url: %(url)s, method:%(method)s'))

    # the default log level is set to WARNING, so
    # we have to explicitly set the logging level
    # to INFO to get our custom message logged.
    app.logger.setLevel(logging.INFO)

    # append the handler to the default application logger
    app.logger.addHandler(handler)

    # let's go
    app.run()

現在はMongoDB層と POST そして、 PATCH そして PUT 方法が記録されている。このアイデアも少し増やすためです INFO そして可能性があります DEBUG 未来の試合を平らにする.

操作日誌

OpLogはすべての編集操作のAPI範囲ログである.間隔を置いて POST そして、 PATCH PUT そして DELETE 操作記録装置に操作を記録することができる。そのコア部分では,操作ログは1つのサーバログにすぎない.異なる点は、クライアントが任意の他のAPIエンドポイントを問い合わせるようにそれを問い合わせることを可能にするために、読み取り専用エンドポイントとして開示することができる点である。

各操作ログエントリには、文書および操作に関する情報が含まれる。

Oplogエントリは、他のAPIによって維持されている文書と同様に開示されている。

  • エントリID

  • ETag

  • HATEOASフィールド(有効であれば)。

もし OPLOG_AUDIT エントリーが有効かどうかはまた表示されます。

  • クライアントIP

  • ユーザー名またはトークン(利用可能であれば)

  • 文書の変更に適用される( DELETE 文書全体を含む).

典型的な動作ログエントリは以下のとおりである.

{
    "o": "DELETE",
    "r": "people",
    "i": "542d118938345b614ea75b3c",
    "c": {...},
    "ip": "127.0.0.1",
    "u": "admin",
    "_updated": "Fri, 03 Oct 2014 08:16:52 GMT",
    "_created": "Fri, 03 Oct 2014 08:16:52 GMT",
    "_etag": "e17218fbca41cb0ee6a5a5933fb9ee4f4ca7e5d6"
    "_id": "542e5b7438345b6dadf95ba5",
    "_links": {...},
}

少しのスペースを節約するために(少なくともMongoDB上で)フィールド名が短縮されている:

  • o 実行された操作を表す

  • r 資源のエンドポイントを代表します

  • i 代表文書ID

  • ip クライアントIPです

  • u ユーザー(またはトークン)を代表する

  • c 発生した変更を代表して

  • extra オプションフィールドであり、カスタムデータを格納するために使用することができる

_created そして _updated ターゲット文書に対しては,ターゲット文書は様々な場合に便利である(たとえばoplogがいつクライアントに利用可能であるかについては後述する).

デフォルトの場合、 c (変更)フィールドは含まれていません POST 運営部。あなたは追加することができます POST 致す OPLOG_CHANGE_METHODS 設定(ご参照) 全体構成. )各挿入時に文書全体を含めることを希望する場合。

掘削機はどのように操作されますか?

OpLogには7つの専用設定があります

  • OPLOG 動作ログ機能をオンおよびオフにします。黙認する. False それがそうです。

  • OPLOG_NAME データベース上のoplog集合の名前である.黙認する. oplog それがそうです。

  • OPLOG_METHODS 記録するHTTPメソッドのリストである.すべてを黙認する。

  • OPLOG_ENDPOINT 終点名です。黙認する. None それがそうです。

  • OPLOG_AUDIT 有効であれば、IPアドレスと変更も記録されます。黙認する. True それがそうです。

  • OPLOG_CHANGE_METHODS どの方法が変更を記録するかを確認します。黙認する. [‘PATCH’,‘PUT’,‘DELETE’] それがそうです。

  • OPLOG_RETURN_EXTRA_FIELD オプションを確定する extra フィールドは OPLOG_ENDPOINT それがそうです。黙認する. False それがそうです。

ご覧のように、デフォルトではoplog機能はオフです。また、なぜなら OPLOG_ENDPOINT 黙認する. None この機能を開いても、パブリックoplogサイトは利用できません。あなたのoplogを一般に公開するためには、エンドポイント名を明示的に設定しなければなりません。

Oplogサイト

Oplogエンドポイントは1つの標準APIエンドポイントにすぎないので、カスタマイズすることができます。これにより、カスタム認証(このリソースが管理目的のためにのみ利用可能であることを望む場合がある)または任意の他の有用な設定を設定することができる。

エンドポイントの設定の大部分を変更することはできますが、サイトは常に読むだけなので、 resource_methods あるいは…。 item_methods 他の場所に行くのではなく ['GET'] 何の役にも立たない。さらに、カスタマイズする必要がない限り、自動的に追加されるので、操作ログエントリをドメインに追加する必要はありません。

複数のクライアント(例えば、携帯電話、タブレット、ネットワーク、デスクトップアプリケーション)が互いにサーバとの同期を保つ必要がある場合には、oplogを1つのエンドポイントとして公開することが有用である可能性がある。彼らは各サイトにアクセスする必要はなく,操作ログにアクセスするだけで前回のアクセスから発生したすべての状況を知ることができる.これはいくつかの要請ではなく、要請だ。これはいつも顧客が取ることができる最善の方法ではない。あるサイトでの変更のみを調べた方がよい場合がある.これも可能であり,oplogを調べてその端点で発生した変更を知るだけでよい.

Oplogエントリを拡張する

操作ログが更新されるたびに on_oplog_push 事件が触発される。1つまたは複数のコールバック関数をこのイベントに連結することができます。コールバック受信 resource そして entries 論拠として。前者は資源名であり,後者はディスクに書き込まれる操作ログエントリリストである.

コールバックはオプションを追加することができます extra フィールドは、仕様動作ログエントリに追加されます。このフィールドは、任意のタイプであってもよい。本例では、各エントリにカスタム辞書を追加する:

def oplog_extras(resource, entries):
    for entry in entries:
        entry['extra'] = {'myfield': 'myvalue'}

app = Eve()

app.on_oplog_push += oplog_extras
app.run()

明確に設定されていない限り注意してください OPLOG_RETURN_EXTRA_FIELD 至る True vt.的 extra フィールドは not 次のようにする. OPLOG_ENDPOINT それがそうです。

注釈

あなたはMongoDBにいますか?操作ログを設定することを考える capped collection それがそうです。また、もしそうかどうか知りたいなら、前夜のブログのインスピレーションは明らかに畏敬の念に由来しています。 Replica Set Oplog それがそうです。

構造最終ノード

Eveのモードエンドポイントを有効にすることにより、APIクライアントにリソースモードを公開することができる。そのためには SCHEMA_ENDPOINT 構成オプションは、そこからアーキテクチャデータを提供するAPIエンドポイント名に設定されます。有効になると,EVEは端点を1つの読み出し専用資源と見なし,その中にJSONコードを含むCerberusパターンを定義し,資源名ごとにインデックスを作成する.リソースの可視性および許可設定がサポートされているため、アーキテクチャの終端ノードでは内部リソースにアクセスできないか、認証されていないリソースを要求することになります。デフォルトの場合、 SCHEMA_ENDPOINT とする. None それがそうです。

MongoDB統合フレームワーク

支持する. MongoDB Aggregation Framework 内蔵されています。以下の例(PyMongoからとる)では,集合全体の落札配列における各トークンの出現回数を計算する簡単な収束を行う.これを達成するためには、私たちはパイプに三つの操作を伝達しなければならない。まず,トークン配列を展開し,タグごとにグループ化して和を求め,最後にカウント順にソートする必要がある.

Python辞書は秩序を維持していないので、使うべきです SON あるいは集合する OrderedDict 明示的な順序付けが必要な位置、例えば $sort

posts = {
    'datasource': {
        'aggregation': {
            'pipeline': [
                {"$unwind": "$tags"},
                {"$group": {"_id": "$tags", "count": {"$sum": 1}}},
                {"$sort": SON([("count", -1), ("_id", -1)])}
            ]
        }
    }
}

上のパイプは静的です。あなたは動的パイプラインを可能にすることができ、クライアントは集約結果に直接影響を与える。パイプを少し更新してみましょう

posts = {
    'datasource': {
        'aggregation': {
            'pipeline': [
                {"$unwind": "$tags"},
                {"$group": {"_id": "$tags", "count": {"$sum": "$value"}}},
                {"$sort": SON([("count", -1), ("_id", -1)])}
            ]
        }
    }
}

ご覧のように count フィールドは今 $value これは、クライアントが要求を実行する際に設定される。

$ curl -i http://example.com/posts?aggregate={"$value": 2}

上記の要求は、サーバ上での使用につながります count フィールドは静的に構成されている {{"$sum": 2}} それがそうです。クライアントは aggregate パラメータを問い合わせ、次いで、フィールド/値ペアを有する辞書を渡す。他のすべてのキーワードと同様に、変更することができます aggregate お好きなキーワードは、設定するだけです QUERY_AGGREGATION あなたの設定で。

PyMongo自身がサポートするすべてのオプションを設定することもできます。集約に関するより多くの情報は、参照されたい 高度なデータソースモデル それがそうです。

あなたは通過することができます {{}} 無視するフィールドに追加します。以下のパイプを考える.

posts = {
    'datasource': {
        'aggregation': {
            'pipeline': [
                {"$match": { "name": "$name", "time": "$time"}}
                {"$unwind": "$tags"},
                {"$group": {"_id": "$tags", "count": {"$sum": 1}}},
            ]
        }
    }
}

以下の要求が実行された場合:

$ curl -i http://example.com/posts?aggregate={"$name": {"$regex": "Apple"}, "$time": {}}

舞台 {{"$match": {{ "name": "$name", "time": "$time"}}}} パイプラインでは実行されます {{"$match": {{ "name": {{"$regex": "Apple"}}}}}} それがそうです。そして、以下の要求:

$ curl -i http://example.com/posts?aggregate={"$name": {}, "$time": {}}

舞台 {{"$match": {{ "name": "$name", "time": "$time"}}}} 完全にスキップされます

上記の要求は無視します "count": {{"$sum": "$value"}}}} それがそうです。自己定義コールバック関数は付加することができる before_aggregation そして after_aggregation 事件とリンクする。詳細についてはご参照ください 事件とリンクする. それがそうです。

局限性

クライアントがページを分ける (?page=2 )は、デフォルトで有効状態にあります。現在これは $facet ステージには2つのサブパイプ,TOTAL_COUNTが含まれている ($count )とページ分け結果(_S) ($limit まず、そして $skip )を重合パイプの最後尾に追加します。 before_aggregation フック。以下の内容を設定することでページを閉じることができます pagination 至る False 端点に用います。ページを無効にすると、すべての集約結果が各応答に含まれることを覚えておいてください。予期される応答負荷が大きくない場合にのみ、ページを無効にすることが適切である(実際にも望ましい)。

クライアント分類 (?sort=field1 )集約エンドノードではサポートされていません。もちろんです。一つ以上追加することができます。 $sort ステージは上の例でやったようにパイプに追加されますもしあなたが確かに1つ追加したら $sort ステージはパイプに追加されますので、ライン末尾に追加することを考えてください。MongoDBによる $limit 書類 (link) :

一人になる $sort 直後の $limit パイプでは、ソート操作はトップのみを維持します n その結果その中で n 指定された制限ですが、MongoDBは格納するだけです n メモリの中の項目です。

前に見たようにページを追加しました $limit 舞台はパイプの突き当たりまで。ページを区切ることができれば $sort 配管の最終段階であれば,得られた組合せ管を最適化すべきである。

単一のエンドポイントは、通常の結果および集約結果に同時にサービスすることはできない。ただし,複数のエンドポイントを設定することができるため,すべてのエンドポイントが同一のデータソースにサービスを提供する(参照されたい). 複数のAPIエンドポイント、1つのデータソース )により、類似した機能を容易に実現することができる。

MongoDBおよびSQLサポート

ボックスを開くと、単一または複数のMongoDBデータベース/サーバをサポートすることができます。SQLAlChemy拡張は、SQLバックエンドのサポートを提供します。追加のデータ層を比較的容易に開発することができる.訪問 extensions page コミュニティ開発のデータ層と拡張されたリストを表示します。

フラスコから電力を供給する

イヴは Flask マイクロWebフレームワーク。実際,Eve自体はFlaskサブクラスであり,これはイヴが内蔵された開発サーバやそのようなすべてのFlask機能や詳細を公開していることを意味する. debugger, 統合支援 unittesting 1つと extensive documentation それがそうです。