0

Using spray-json on an Akka HTTP server; how can I "assume Content-type: application/json" for requests when not supplied?

Issue

curl localhost:12345/request -d'{"sample":"json"}'

doesn't work unless I add

-H "Content-type: application/json"

explicitly.

Why I ask

  • not ideal for showing succint examples on a README.md
  • annoying to add the header manually all the time while debugging
mlg
  • 1,447
  • 15
  • 19
  • because -d sends it as content-type `application/x-www-form-urlencoded`, but your server only accepts `application/json` – prayagupa Mar 18 '17 at 04:42
  • I don't think the server only accepts `application/x-www-form-urlencoded`; before switching to `spray-json` I was using `jackson` and it didn't require setting a `Content-type`. – mlg Mar 18 '17 at 04:48
  • I'm sayiing your API Server accepts json content only( not in general) – prayagupa Mar 18 '17 at 04:50
  • Yep, my bad; I meant `s/only accepts/rejects/` – mlg Mar 18 '17 at 05:01

1 Answers1

0

You should have defined you API to accept content-type json only, thats why it does not accept other content-types.

Just doing curl -XPOST -d 'content' URL will post your content as application/x-www-form-urlencoded (default behaviour).

See --verbose of curl POST, see Content-Type in example below

$ curl -XPOST -d '{"test" : "testValue"}' "https://jsonplaceholder.typicode.com/posts" -v
*   Trying 104.31.87.157...
* Connected to jsonplaceholder.typicode.com (104.31.87.157) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate: sni233425.cloudflaressl.com
* Server certificate: COMODO ECC Domain Validation Secure Server CA 2
* Server certificate: COMODO ECC Certification Authority
* Server certificate: AddTrust External CA Root
> POST /posts HTTP/1.1
> Host: jsonplaceholder.typicode.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 22
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 22 out of 22 bytes
< HTTP/1.1 201 Created
< Date: Sat, 18 Mar 2017 04:54:41 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 51
< Connection: keep-alive
< Set-Cookie: __cfduid=d91d0ebbaa5f7b40a998d327ffce2b5671489812881; expires=Sun, 18-Mar-18 04:54:41 GMT; path=/; domain=.typicode.com; HttpOnly
< X-Powered-By: Express
< Vary: Origin, X-HTTP-Method-Override, Accept-Encoding
< Access-Control-Allow-Credentials: true
< Cache-Control: no-cache
< Pragma: no-cache
< Expires: -1
< X-Content-Type-Options: nosniff
< Etag: W/"33-cwlRczABGtsoiZUP8lw9WSIt684"
< Via: 1.1 vegur
< Server: cloudflare-nginx
< CF-RAY: 3415986bb9f50c35-SEA
< 
{
  "{\"test\" : \"testValue\"}": "",
  "id": 101
* Connection #0 to host jsonplaceholder.typicode.com left intact
}

You have to change your client headers to match what the API server accepts.

$ curl -H "Content-type: application/json" -XPOST -d '{"test" : "testValue"}' "https://jsonplaceholder.typicode.com/posts" -v
*   Trying 104.31.87.157...
* Connected to jsonplaceholder.typicode.com (104.31.87.157) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate: sni233425.cloudflaressl.com
* Server certificate: COMODO ECC Domain Validation Secure Server CA 2
* Server certificate: COMODO ECC Certification Authority
* Server certificate: AddTrust External CA Root
> POST /posts HTTP/1.1
> Host: jsonplaceholder.typicode.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-type: application/json
> Content-Length: 22
> 
* upload completely sent off: 22 out of 22 bytes
< HTTP/1.1 201 Created
< Date: Sat, 18 Mar 2017 04:53:22 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 38
< Connection: keep-alive
< Set-Cookie: __cfduid=d8e90de27fc1fa87fb42b763a4199ba7d1489812801; expires=Sun, 18-Mar-18 04:53:21 GMT; path=/; domain=.typicode.com; HttpOnly
< X-Powered-By: Express
< Vary: Origin, X-HTTP-Method-Override, Accept-Encoding
< Access-Control-Allow-Credentials: true
< Cache-Control: no-cache
< Pragma: no-cache
< Expires: -1
< X-Content-Type-Options: nosniff
< Etag: W/"26-Zx6VPi+rfbM5YFlBzT2pzGEHcgg"
< Via: 1.1 vegur
< Server: cloudflare-nginx
< CF-RAY: 3415967b2af12a19-SEA
< 
{
  "test": "testValue",
  "id": 101
* Connection #0 to host jsonplaceholder.typicode.com left intact
}

You can change the content-type on you server, and change whatever content you receive to JSON by yourself (which might not a good idea though)

prayagupa
  • 30,204
  • 14
  • 155
  • 192