Webmachine POST Example

Many people have asked for an example Webmachine resource that responds to POST. If you follow my twitter feed, you may have caught this gem.

I figured that example could use a little fleshing out, so I’ve added a resource to my wmexamples repo.

formjson_resourc.erl makes an attempt at demonstrating the simplest way to handle a POST, while also demonstrating the difference between content-producing functions (to_json/2 in this example, and others named in content_types_provided/2), which put content in the response body simply by returning it, and other functions, which have to put content in the response body by returning a modified ReqData.

For another example of handling POST, read demo_fs_resource.erl that comes with Webmachine. It implements post_is_create/2, create_path/2, content_types_accepted/2, and accept_content/2 to handle POST requests. (Incidentally, demo_fs_resource is a good example of many Webmachine resource functions.)

Updated to include content_types_accepted/2 in the list of functions handling POST requests – thanks for catching it, Lou!

About these ads

7 comments so far

  1. Sebastian on

    Great stuff!
    Thanks!

    All the best,
    Sebastian

  2. pablo on

    Why when receiving a GET the response is just the first term in the tuple at the end of to_json {json_body(wrq:req_qs(RD)), RD, Ctx}.

    and when receiving a POST you have to use append_to_response_body ?

    In addition, append_to_response_body(binary(),rd()) -> rd() returns ReqData. Isn’t ReqData misleading considering it is used both for request and response data?
    Can I find a definition of this record?

    Thanks

  3. Bryan on

    Hey, Pablo. I think Justin covered most of this on the Webmachine mailing list here: http://bit.ly/Gc2At

    But, the short answer is that body-producers (for example, to_json) return bodies because GET is defined as returning a representation, while post-handlers must add bodies if they want because POST is largely open-ended, and certainly not required to return a body.

    As for the ReqData confusion, as with many other frameworks, “request” here is used to define the entire processing of the HTTP request, not just the content and headers provided by the client.

    The record that represents the ReqData parameter is defined by the wrq module. It is recommended that you use the functions in the wrq module to modify the structure instead of poking at it directly. Its methods are also covered on the wiki: http://bitbucket.org/justin/webmachine/wiki/WebmachineReqData

  4. lou on

    Hi Bryan,

    I’m having a problem processing a POST request. The problem lies when using create_path… it returns a 415 Unsupported Media Type which does not seem possible given the diagram. This problem only occurs when using a create_path in the code. Setting post_is_create to false solves the problem but I need to use create_path so that is not an option.

    -Lou

  5. pablo on

    When using post_is_create and create_path webmachine treats your request as a PUT with the path you return from create_path. I think you need to indicate the content type you are expecting and the handler in content_types_accepted
    because that’s the way PUT works in webmachine.

    The method in ReqData will still be POST and the path won’t go through the dispatcher so you’ll get it using wrq:disp_path(ReqData). Maybe it’ll be better to process the url again?

  6. Bryan on

    Hi, Lou. I see the trouble – I left content_types_accepted/2 out of the list of functions that demo_fs_resource implements in order to handle POST requests. Sorry about that, I’ve added it now. Just to reinforce what Pablo said:

    You need two things:
    1. a Content-Type header in the POST request
    2. a content_types_accepted function in your resource, returning a clause that matches the content-type header in the request

    Once you have both of these, instead of ending up at 415, Webmachine will call the function named in content_types_accepted, and in that function you can handle the rest of the POST as if it were a PUT.

    Make sense?

  7. lou on

    @pablo Thanks, it works now. As you said, we need to add content_types_accepted.

    @Bryan Thank you very much. I understand how POST works in webmachine much better now. I also looked at the webmachine decision core itself and saw that redirect() itself actually has a possibility to return a 415 when it calls accept_helper(). This happens when the code cannot see a content_types_accepted() written by the user.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: