Node.jsのRESTのAPIでの非伝統的なクエリを処理する方法

ジェームズPavett:

私はいくつかのPHPとフロントエンドのJavaScriptの経験を持っているが、私は特定の概念を動き回るのに苦労していますが、私のアプリケーションの一つのVue.jsクライアント側にサービスを提供するためにNode.jsのREST APIを作るしようとしています。これまでのところ私は主にドキュメントとオンラインガイド以下となっています。

私はExpress.jsとMySQLデータベースを使用しています。

この例では、私は、お客様自身を定義し、顧客のモデルを持っている、との方法は、データベースと対話します。

// constructor
const Customer = function(customer) {
  this.email = customer.email;
  this.name = customer.name;
  this.active = customer.active;
  this.created_at = customer.created_at
};

Customer.getAll = result => {
  sql.query("SELECT * FROM customers", (err, res) => {
    if (err) {
      console.log("error: ", err);
      result(null, err);
      return;
    }

    console.log("customers: ", res);
    result(null, res);
  });
};

...

それから私は、コントロールのメソッドが呼び出され、顧客のコントローラを持っており、フロントエンドにそれを取得する前に、いずれかの操作を行います。

const Customer = require("../models/customer.model.js");

exports.findAll = (req, res) => {
  Customer.getAll((err, data) => {
    if (err)
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving customers."
      });
    else res.send(data);
  });
};

...

この設定は、基本的なCRUD操作のために動作しますが、私は戻って、ユーザーの特定のセットをプルを行うと、全体ではなく、一連の操作を実行したい場合。

例えば、私は最後の3ヶ月間、月ごとに作成顧客数のリストを取得したいと思います:

11/2019 200
12/2019 234
01/2020 122

私は必要な形式でデータを返す私のモデルに新しいメソッドを追加する必要がある、または私はそれダウンが供給パラメータに依存のgetAllメソッドとフィルタを利用して、コントローラに新しいメソッドを追加する必要がありますか?私は、クエリのための特定の要件の多くを持っている場合は、すぐに手に負えなくなる可能性がモデルに新しいメソッドを追加することだと思うしかし、もし私がすべてを取得していて非効率ですコントローラ内のデータのフルセット、ダウンIフィルタ私はちょうどそれの大半を無視しようと思って最初にデータベースからのデータ。

おそらく私は完全に的外れだと、これらのアプローチの両方が正しくないだろう。

編集します

これは、追加の透明性を提供することです。

私は私が私のモデルとルートに次のコードの部分を追加し所望の出力を達成することができます:

Customer.getCreatedByMonth = result => {
    sql.query("select DATE_FORMAT(created_at, '%m/%Y') as month, count(*) as count from customers group by DATE_FORMAT(created_at, '%m/%Y')", (err, res) => {
        if (err) {
            console.log("error: ", err);
            result(null, err);
            return;
        }

        console.log(res);
        result(null, res);
    });
};

app.get("/customers/monthly", customers.findCreatedByMonth);

これは、しかし、それを行うには非常にきれいな方法のように感じていない、と私は新しいルートを追加し、それにはアクセス/命名された方法でいくつかのCRUDの規則を破っていますように私は感じます。

私は、SQLを知っているし、理想的に私は、私はまだノードを勉強していて見てORMを避けたいです。

mootrichard:

私は、これは本当にあなたのAPIの消費者に依存しており、実際にNodeJSに質問固有のものではないと信じています。

あなたがでリソースを持っている/customers、との基本的なCRUDのためにあなたが持つかもしれないGETPUTPOSTDELETE方法。

このように設計されてRESTfulなAPIでチラッと見を取って、私はそれを引き受けるGET/customersエンドポイントは私の顧客のリストや配列を返します。

パスを作成するには/customers/monthly、次のフィルタに似て聞こえる追加機能を記述しようとしています。月刊音が、どちらかヶ月に濾過またはグループ化された顧客のリストを返すようにしようとしているのが好きです。

どのようなコメントで他の人がをほのめかしているように見えることは、これは潜在的にクエリ文字列パラメータを使用して解くことができることです。追加パスを追加するのではなく/customers、あなたのような何かを提供します/customers?groupBy=month

あなたのモデルに複雑さを追加しないようにしたいように聞こえるが、私はあなたが基本的なCRUD操作の外を移動しているとき、それは避けられないと思います。あなたは持っている必要があり、いくつかの SQL操作にHTTPリクエストを変換する方法を。

もう一つの問題は、適切なデータを取得するために、モデルやコントローラの責任をすべきでしょうか?それはおそらく責任を負わなければならないので、モデルは、データに最も近い住んでいます。

あなたのデータセットが得ることができるどのように大きなに応じて、それはすべてのレコードを取得し、コントローラレベルでダウンフィルタリングすることは非現実的になる可能性があります。コントローラは本当に適切なデータを取得することができるように、モデルのためのクライアントの要求を翻訳して、取得されたデータは、クライアントがそれを受け取ることができるようにフォーマットされていることを確実にするための責任を負わなければなりません。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=7624&siteId=1