What to do when you need more verbs in REST

前端 未结 4 665
无人共我
无人共我 2021-01-30 11:32

There is another similar question to mine, but the discussion veered away from the problem I\'m encounting.

Say I have a system that deals with expense reports (ER). Yo

4条回答
  •  醉梦人生
    2021-01-30 11:48

    For manipulating the status of resources I often like to use "status buckets". The idea is that when you "add" an object into that bucket, it gets that status. It is like having in and out boxes on your desk. The location of the document defines its status.

    So, you could do something simple like:

    POST /Expenses/Approved
    { .. Expense document ... }
    

    or for the more complex case that you hinted at in your document where multiple people have to approve the document.

    POST /ExpenseApprover/John/ApprovedExpenses
    { .. Expense document ... }
    

    If you need to submit an expense report for approval you can do

    POST /ExpenseApprover/John/Pending
    { .. Expense document ... }
    

    And don't forget hypermedia can make this process workflow enabled. Imagine someone creates an initial expense report, the server could response with the following JSON.

    { "id" : "234",
      "title": "Trip to NY", "totalcost": "400 USD",
      "submit_url": "/ExpenseApprover/John/Pending"
    }
    

    The client can POST to the submit_url to move the expense onto it's next step. Then when John retrieves the expense, he gets

    { "id" : "234",
      "title": "Trip to NY", "totalcost": "400 USD",
      "approve_url": "/ExpenseApprover/Finance/Pending",
      "denied_url": "/ExpenseApprover/John/Denied",
    }
    

    When the finance department do a

    GET /ExpenseApprover/Finance/Pending
    

    they could get a list of Pending Expenses,

    { PendingExpense: [
        { "id" : "234",
          "title": "Trip to NY", "totalcost": "400 USD",
         "approve_url": "/Expense/Approved",
         "denied_url": "/ExpenseApprover/Finance/Denied",
        }
       ]
    }
    

    Forgive my horrible JSON, but I hope you get the idea that including the link in the response you can guide the flow of your application. You can also stop worrying so much about what the url looks like because the client doesn't really care. The client reads the url from the response based on the property name and dereferences it. You can change your mind a million times on what the best url structure is and your clients will not be affected. Just don't change the property name!

    These "status bucket" urls are used to hold a set of resources that have a similar status. The idea is that you POST a document into the collection:

    POST /ExpenseApprover/Finance/Denied
    
    {"id" : "234", "title": "Trip to NY", "totalcost": "400 USD"}
    

    It is not necessary to uniquely define the particular expense that you are adding in the URL because the body document should contain some kind of identifying key value.
    This technique is just as valid for flagging expenses has having discrepancies. You simply create a new resource that holds expenses with discrepancies and post your expense report into to it.

    POST /Discrepancies
    {"id" : "234", "title": "Trip to NY", "totalcost": "400 USD"}
    

提交回复
热议问题