データについては、行動を語りましょう.


あなたは私に古い学校にラベルをつけます、しかし、私は本当に私のフロントエンドと私のバックエンドが強く分離されるのが好きです.私は、その理由のために完全なJavaScriptに行く衝動に抵抗しました.バックエンドでPythonやPHPを使うならば、怠惰は勝ちます、そして、あなたはフロントエンドのJS/TSであなたのオブジェクトとモデルを再実行しません.そこで、時間は何か他のことを行うに費やすことができます.
あなたが尋ねるかもしれないことをすること?私たちのユーザーの経験について考える.私は開発者として、私たちは確かに私たち(デザイナー、UX、マーケティング)のためにそれを行うには、他の人に依存していることを発見した.それで、彼らと話をする必要がないために、我々は前にデータモデルを許して、再実行します.それが役に立つので、右?
じゃない.
まず最初に、最も基本的な理由のために、バックエンドにそれほど多くのデータがありません.そして、それさえ単純でありません.プライベートなプライベートデータがあり、プライベートデータにはユーザが見る権利があります.
フロントエンドでは,データプレゼンテーションは文脈に依存する.それで、あなたがフロントエンドにバックエンドに持っているものを翻訳することは、幻の探求です.
次に、フロントエンドのモデルを再実装しようとすると、リレーションシップを再実装します.そしてそれらを保存します.選択したツールとして、GraphSQLとLocalStorageを呼び出します.彼らは本当にいい.しかし、あなたのユーザーが何をしたいかわからないなら、彼らはあなたが何かを成し遂げるのを助けません.
あの二つの言葉は、私にとって大切なことの核心にあります.
  • どのようなユーザーが行うことができます
  • ユーザーコンテキストとは
  • ユーザーが本当にモデルについて気にしないので.より頻繁に、ユーザーの精神モデルは、ソフトウェアモデルで1 - 1でさえありません.何故なら人間の心はより柔軟であるからreference database type そして、あなたのユーザーはおそらくそれ自身のビジネス(ソックスの販売、木材を切断したり契約書を管理)よりもあなたがそれを考えることによって占有されます.
    ユーザーはショートカットを望みます.
    お使いのユーザーは、サーバーのCPUを使用したい、たくさん.データを意味のある方法で変換したい.最後に、あなたのサーバー上のきれいなモデルを格納するデータは、実際の世界で使用することができない場合、それらに無駄です.あなたのユーザーは、ソックス、ログ、ブロードキャストレポートで動作し、彼らはすでに自分の倉庫に実際の実データを持っている.
    あなたのユーザーが望んでいないものは、彼らがデータベース関係に何をしているかを翻訳することです.彼らは気にしない.
    彼らは靴下のパックをマークしたくない"status": SHIPPED , 彼らはそれを出荷したい.彼らについて話すなstatus プロパティShipmentRowShipment オブジェクト.それは彼らにとって意味がない.
    そして、それがスクリーンの前でユーザーに無意味であるならば、それは多分フロントエンドコードでそれを含むことは役に立たないでしょう.
    簡単な例を挙げましょう.
    のは、私たちのユーザーは、ソックスの売り手は、注文(2赤&黄色と1赤&青)それのウェブサイト上にあるとしましょう.
    エンドユーザーのクライアントは電話で電話をして、「最後に、申し訳ありませんが、私は緑と青が欲しくありません」と言います.
    典型的なアプリケーションでは、次のようにします.
    GET /shipments
    200 =>
    [
     {"id": 1234,
      "title": "Shipment of socks",
      "status": "PENDING_SHIPMENT",
      "rows: [
        {"id": "1234-1", "quantity": 2, "product_name": "Red & Yellow"},
        {"id": "1234-2", "quantity": 1, "product_name": "Green & Blue"}
      ]
     },
     {/* another shipment */}
    ]
    
    DELETE /shipment/1234/row/2
    205 =>
    "deleted"
    
    PUT /shipment/1234
    {"status": "SHIPPED"}
    205 =>
    "updated"
    
    それは3 HTTPリクエストです.クリックしてリストを取得するには、1つの余分な行を削除するには(多分1つの削除を確認するには、1余分な場合は、UIは“チェックボックス+送信”)、1つの選択のステータスを変更するには、1つのフォームを提出する:合計5±1.
    また、接続されたユーザーが参照する権利があるかどうかを確認するために3バックエンドのアクションでACLロジックを実装し、行を削除し、それを出荷する必要があります.そして、関連するボタンを表示するようにフロントエンドで同じロジックを実装する必要があります.
    さあ、ユーザーの行動と文脈を考えてみましょう.
    まず始めましょうGET .
    GET /shipments
    200 =>
    {
     "shipments":[
       {"id": 1234,
        "title": "Shipment of socks",
        "rows": [
          {"id": "1234-1", "quantity": 2, "product_name": "Red & Yellow", "user_can": ["change_row_quantity"]},
          {"id": "1234-2", "quantity": 1, "product_name": "Green & Blue", "user_can": ["change_row_quantity"]}
        ],
        "user_can": ["ship", "cancel"]
       }
     ],
     "actions":{
        "ship":{"method":"POST", "href":"/shipment/:id/ship", 
                "params":{
                    "mode":{
                      "type": "enum", 
                      "values": "FULL|PARTIAL"
                    }
                }
               },
        "cancel": {"method":"DELETE", "href":"/shipment/:id"},
        "change_row_quantity": {"method": "PUT", "href":"/shipment_row/:id/quantity", "params": {"quantity": {"type": "posint"}}},
        "destination_change": {"method":"PUT", 
                               "href":"/shipment/:id", 
                               "params": {"address":{"type": "Address"}}
                              }
      }
    }
    
    そこには、すべてを持っているし、出荷の目的地を変更することも知っていなかった.さて、あなたのユーザーはできません、バックエンドはそれを言いました.フロントエンドのロジックを実装する必要はありません.サブアクションを宣言することもできますShipmentRows を返します.フロントエンドは応答を読み、それに応じてその仕事をしなければなりません.
    さて、1234の命令を部分的に出荷しましょう!フロントエンドでそれを構成する必要はありません、HREFとParamsは、そこで文書化されます.
    POST /shipment/1234/ship
    {"mode": "PARTIAL"}
    400 =>
    {"error": "missing_parameter", 
     "missing_parameter": {
         "kept_rows": {
            "type": "int[]",
            "suggested_values":[
              {"key": "1234-1", "label": "Red & Yellow"},
              {"key": "1234-2", "label": "Green & Blue"}
            ]
         }
    }
    
    何が起こったのですか.我々はそれを維持したい行を伝えることなく、それを出荷しようとしました!私たちは、リストのパラメータに追加することができましたが、ユーザーのためのショートカットを作成しようとすると、我々はあまり期待していないし、それが現在対処する必要がないことでフロントエンドを負担する必要はありません.
    また、バックエンドのエラーコードを使用してフローを作成することもできます.
    そして、フロントエンドに役立つはずです.ここでは、我々はちょうど言ったことができましたmissing_parameter: kept_rows また、フロントエンドの動作を実装するために外部のドキュメントに依存します.しかし、我々は、フロントエンドが考えさえしないように、余分のマイルとリターンドキュメンテーションと提案されたデータを歩くことに決めました!いいかな?
    この場合、私は通常、提案された欠落しているパラメータでpopinを表示します.そして、正確に同じリクエストを送信、濃縮.そのPopinには、選択されていない行が失われることを警告メッセージが含まれています(私は、“削除”と言うことはありません.なぜなら、人々は“undelete”ことができると思うからです).
    POST /shipment/1234/ship
    {"mode": "PARTIAL", "kept_rows": ["1234-1"]}
    200 =>
    {
     "shipment":
       {"id": 1234,
        "title": "Shipment of socks",
        "shipped_at": "2020-10-05 10:00:00",
        "rows": [
          {"id": "1234-1", "quantity": 2, "product_name": "Red & Yellow"},
        ],
        "user_can": ["return"]
       }
     ,
     "actions":{
        "return": {"method":"POST", "href":"/shipment/:id/return"}
      }
    }
    
    最後に、出荷された更新情報を出荷します.The shipped_at プロパティは前に意味をなさなかったので、省略されました、私たちはフロントエンドに対処したくありませんnull または無意味な値.それが役に立つ今、我々はそれを返します.
    利用可能なアクションが更新され、これはフロントエンドに反映される必要があります.
    ここで、再び、3つのHTTP呼び出しは、2つの終点だけで呼び出します.しかし、1つだけをクリックしてリストを表示するには、“部分的な出荷”、1つを維持する行を選択し、1つのフォーム= 4をクリックして合計をクリックして選択します.それは物事を成し遂げるために20 %少ない摩擦です.
    これは、一度だけロジックを実装するため、フロントエンドにメンテナンスを保存します.
    あなたが行動することができないものを実装しないので、それは至る所で保存される仕事です.
    ユーザーコンテキストは、バックエンドで完全に統合され、その仕事は、フロントに送信されますが、その仕事は、ユーザーの外骨であることを、彼らのパワーとアクションを増幅することです.
    クレジットヘッダー写真ありがとうMark Chan を返します.