Skip to content

Instantly share code, notes, and snippets.

@fmasion
Created November 27, 2013 22:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fmasion/7684499 to your computer and use it in GitHub Desktop.
Save fmasion/7684499 to your computer and use it in GitHub Desktop.
Here a way to get around play issue #2015 This will enable you to add a body to WS GET and DELETE methods It uses an Implicit value class to extend WSRequestHolder The only "trick" is to use the same package name to overcome the private[Play] limitation Enjoy
// KEEP CARE TO LET THIS IN THIS PACKAGE
// this enables you to acces and extend private[Play] Objects
package play.api.libs.ws
import scala.concurrent.Future
import java.io.File
import play.api.http.{ Writeable, ContentTypeOf }
import play.api.libs.ws.WS._
import play.api.libs.iteratee.Iteratee
// Implicits are used to extend WSRequestHolder to enable body to be passed with GET and DELETE Methods
// Won't be needed after issue #2015 will be fixed
object Implicits {
implicit class WSRequestHolderOps(val rh: WSRequestHolder) extends AnyVal {
/**
* Perform a GET on the request asynchronously.
* @param body supplied won't be chunked
*/
def get[T](body: T)(implicit wrt: Writeable[T], ct: ContentTypeOf[T]): Future[Response] = rh.prepare("GET", body).execute
/**
* Perform a GET on the request asynchronously.
* @param body supplied won't be chunked
*/
def get(body: File): Future[Response] = rh.prepare("GET", body).execute
/**
* performs a get with supplied body
* @param body won't be chunked
* @param consumer that's handling the response
*/
def get[A, T](body: T, consumer: ResponseHeaders => Iteratee[Array[Byte], A])(implicit wrt: Writeable[T], ct: ContentTypeOf[T]): Future[Iteratee[Array[Byte], A]] =
rh.prepare("GET", body).executeStream(consumer)
/**
* Perform a DELETE on the request asynchronously.
* @param body supplied won't be chunked
*/
def delete[T](body: T)(implicit wrt: Writeable[T], ct: ContentTypeOf[T]): Future[Response] = rh.prepare("DELETE", body).execute
/**
* Perform a DELETE on the request asynchronously.
* @param body supplied won't be chunked
*/
def delete(body: File): Future[Response] = rh.prepare("DELETE", body).execute
/**
* performs a delete with supplied body
* @param body won't be chunked
* @param consumer that's handling the response
*/
def delete[A, T](body: T, consumer: ResponseHeaders => Iteratee[Array[Byte], A])(implicit wrt: Writeable[T], ct: ContentTypeOf[T]): Future[Iteratee[Array[Byte], A]] =
rh.prepare("DELETE", body).executeStream(consumer)
}
}
....
import play.api.libs.ws.WS
// Add this to the regular WS imports
import play.api.libs.ws.Implicits._
...
// Now you can you the magicaly added Methods on WS object
WS.url(url).get(body)
WS.url(url).get(file)
WS.url(url).get(body, (_ => MyIteratee))
WS.url(url).delete(body)
WS.url(url).delete(file)
WS.url(url).delete(body, (_ => MyIteratee))
@yingdanh
Copy link

How to implement this in Java?

@gkini
Copy link

gkini commented Aug 6, 2014

This was very helpful. Thanks

@ajmnsk
Copy link

ajmnsk commented Jun 7, 2017

This was helpful.
And one more way to overcome Play limitations (Play documentation recommendation) is to get access to underlying AsyncHttpClient, and use this: https://www.playframework.com/documentation/2.5.x/ScalaWS#Accessing-AsyncHttpClient

import org.asynchttpclient.AsyncHttpClient
val client: AsyncHttpClient = ws.underlying[AsyncHttpClient]

@scalaster
Copy link

Hi
I was able to post a body with the delete request using the withBody() method

wsClient.url(url)
      .withBody(body)
      .delete()
      .map (response => if (response.status == Status.NO_CONTENT) true else false)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment