Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lift REST service not recognizing PUT request

I'm implementing a REST service with the Lift web framework in Scala and I'm having some issues with the PUT request to create a new entity for which I know the ID.

Already added the dispatch to Boot.scala and my rest service object looks a bit like this:

package code
package lib

import model._

import net.liftweb._
import common._
import http._
import rest._
import util._
import Helpers._
import json._

object RestService extends RestHelper {

  serve( "api" / "room" prefix {
    // /api/room returns all the rooms
    case Nil JsonGet _ => Room.registredRooms: JValue
    // /api/room/count gets the room count
    case "count" :: Nil JsonGet _ => JInt(Room.registredRooms.length)
    // /api/room/room_id gets the specified room (or a 404)
    case Room(room) :: Nil JsonGet _ => room: JValue
    // DELETE the room in question
    case Room(room) :: Nil JsonDelete _ => 
      Room.delete(room.id).map(a => a: JValue)
    // PUT adds the room if the JSON is parsable
    case Nil JsonPut Room(room) -> _ => Room.add(room): JValue

    // POST if we find the room, merge the fields from the 
    // the POST body and update the room
    case Room(room) :: Nil JsonPost json -> _ => 
      Room(mergeJson(room, json)).map(Room.add(_): JValue)
  })

}

GET requests are working properly as I tested with:

$ curl http://localhost:8080/api/room/abs
{
  "id":"abs"
}

I am now trying to implement the create service and I keep getting a 404 not found when I PUT:

$ curl -i -H "Accept: application/json" -X PUT -d "[{'id':'abs'}]" http://localhost:8080/api/room/
HTTP/1.1 404 Not Found
Expires: Sun, 4 Sep 2011 14:13:50 UTC
Set-Cookie: JSESSIONID=t1miz05pd5k9;Path=/
Content-Length: 106
Cache-Control: no-cache, private, no-store
Content-Type: text/html; charset=utf-8
Pragma: no-cache
Date: Sun, 4 Sep 2011 14:13:50 UTC
X-Lift-Version: 2.4-M3
Server: Jetty(6.1.22)

<!DOCTYPE html>
<html> <body>The Requested URL /api/room/ was not found on this server</body> </html>

On SBT I can see that the request is being recognized as a PUT request:

15:13:50.130 [414557038@qtp-135607724-2 - /api/room/] INFO  net.liftweb.util.TimeHelpers - Service request (PUT) /api/room/ returned 404, took 10 Milliseconds

Any ideas on what might be wrong?

like image 431
José P. Airosa Avatar asked Sep 04 '11 14:09

José P. Airosa


1 Answers

There are three problems with the way you're testing the PUT request.

Most importantly, you need to set the Content-Type header to application/json (instead of or in addition to the Accept header).

Next, you need to use double quotation marks in your JSON: -d '[{"id":"abs"}]'. (Double quotation marks are actually required for strings in valid JSON. Some JSON parsers will accept single quotation marks, but not Lift's.)

Finally, remove the trailing slash from the URL. It's adding "index" to the end of the path list, which means you won't get a match in your case Nil JsonPut... line.

The following should work:

curl -i -H "Content-Type: application/json" -X PUT -d '[{"id":"abs"}]' http://localhost:8080/api/room
like image 68
Travis Brown Avatar answered Sep 22 '22 13:09

Travis Brown