3

I'm working with playframework for final project at university and I'm getting a problem when routing a delete or put method. When I'm requesting a DELETE or PUT methods I'm getting:

[info] play.api.Play - Application started (Dev) [debug] a.ErrorHandler - onClientError: statusCode = 404, uri = /Rest/deleteCity, message ="

My JQuery ajax call is:

$("#scalaDelete").click(function(){
    $("#result").empty();   
    $.ajax({
        url: "http://localhost:9000/Rest/deleteCity",
        method: "DELETE",
        data: {city: "Alvorada"},
        dataType: "json",
        success: function(result){
            $("#result").append("Result: "+result.Result);
        },
        error: function (request, status, error) {
            alert(status);
        }
    });
});

My Route Play Route:

DELETE       /Rest/deleteCity       controllers.RestController.deleteCity()

My Controller Method:

case class UserDelete(city:String)
class RestController @Inject()(db: Database, cc: ControllerComponents) extends AbstractController(cc) {

val userDeleteForm = Form(
   mapping(
     "city" -> text
   )(UserDelete.apply)(UserDelete.unapply)
  )

  def deleteCity = Action{ implicit request=>
    val userPar = userDeleteForm.bindFromRequest.get
    //DatabaseDelete

    Ok(jsonResult)
  }

}

I've already activated cross domain in chrome, I've used a CORS extension for it.

Thanks for helping

tomasz
  • 12,574
  • 4
  • 43
  • 54

2 Answers2

1

This seems related to Restful http delete in play, i.e. DELETE with data can be sketchy.

Instead of passing data, I would just move this to the url:

DELETE       /Rest/deleteCity/:city   controllers.RestController.deleteCity(city: String)
# or with a query string
DELETE       /Rest/deleteCity   controllers.RestController.deleteCity(city: String)

and then do

http://localhost:9000/Rest/deleteCity/Alvorada
# or with a query string
http://localhost:9000/Rest/deleteCity?city=Alvorada

Personally I prefer the latter.

Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
  • Hi Andy, thanks for helping me... I've tried the second one, with QueryString, but I still got Not Found method from play Server. I've taken out the Jquery Data parameters and passed URL with ?city=Alvorada. On Controller method I've added def deleteCity(city:String) =... – Daniel Yanagita Oct 23 '17 at 23:26
  • @DanielYanagita just to try something, is it a case sensitive thing? could you try `/rest/delete-city` (usually that's not an issue...) – Andy Hayden Oct 23 '17 at 23:30
  • @DanielYanagita you removed dataType too? – Andy Hayden Oct 23 '17 at 23:31
  • I haven't removed dataType... I guess it's not a case sensitive problem because on route file is same the link, but I'll try make the request with lower case and let you know! Thanks for your attention buddy – Daniel Yanagita Oct 23 '17 at 23:34
  • in fact is not a case sensitive problem... I've tried in lower case and doesn't work, still getting not found, and besides, post and get are working normally.... – Daniel Yanagita Oct 23 '17 at 23:37
  • I've just tried to remove dataType parameters too and it's really not working. the fun thing is that post is working normally using a form to get parameters binded on request at controller – Daniel Yanagita Oct 23 '17 at 23:43
  • @daniel it's not something silly, like you need to restart sbt (routes sometimes need a restart to take) – Andy Hayden Oct 24 '17 at 00:33
  • Hi @AndyHayden, I really appreciate your attention. In fact, I've already executed a sbt clean compile, but doesn't work yet. I've seen another post here where a guy said some browsers just support get and post method. I made a java httpClient for making those put and delete request and it has worked normally. But something interesting for you to know is that playframework uses akka and this framework does not support DELETE request for security reasons, in fact it wasn't well explained on post. Then if you wanna make a DELETE method you gotta make a post method for complete your code. – Daniel Yanagita Oct 24 '17 at 04:46
0

I agree with @AndyHayden.

Play ignores the body of the DELETE request, that is the correct behavior to my mind, but you can work around by explicitly passing a body parser:

def delete = Action(parse.json) { implicit request =>
  val json = request.body
  val someProp = (json \ "someprop").as[String]
  Ok(s"Prop is: $someProp")
}

(this example was given by one of the developers of the Play itself: https://github.com/playframework/playframework/issues/4606#issuecomment-109192802.)

About the doubts in comments:

I've seen another post here where a guy said some browsers just support get and post method.

POST and GET are only valid for the method attribute of the form tag.

You are using javascript request, so you can use any method that server supports. i.e. DELETE is completely fine there.

But something interesting for you to know is that playframework uses akka and this framework does not support DELETE request for security reasons, in fact it wasn't well explained on post. Then if you wanna make a DELETE method you gotta make a post method for complete your code.

Akka HTTP supports the DELETE request (as well as Play Framework): https://doc.akka.io/docs/akka-http/current/scala/http/routing-dsl/directives/method-directives/delete.html

Andriy Kuba
  • 8,093
  • 2
  • 29
  • 46
  • hi, first of all thanks for helping ;) So, if I've understood what akka documentation said, I've gotta create a route coding it, on route file is not gonna work. I've said that would not support DELETE because my server has answered me a warning saying it wasn't supported for security reasons... I'll try to make it creating a custom route by code. Thanks a bunch – Daniel Yanagita Oct 24 '17 at 12:44
  • Hi @AndriyKuba, Sorry for getting late on testing and feeding back... Then you both were right, there are two ways to implement a delete. First one passing values by post and making a simple post route in route.config. Second one passing values by Get, but for getting success I had to point my Route.config for a route method and code It. – Daniel Yanagita Oct 31 '17 at 06:17