During my work when I need to leverage some ML techniques and I have input and output data with the output column containing categories, I often time need to split the output column into several columns with yes or no values.
Let me explain... So for instance you are involved in logistical regression calculation and your output is set of categories like 1, 2, 3, 4... if you use logistical regression to predict the value, it can come up with 1.4... which is really not a valid category.
In this case, you need to break down output column into several with yes/no values, this way, logistical regression would work by predicting either yes or no.
So how do you do it?
Pandas!
First import pandas >>> import pandas as pd
Then let's say you have following data. >>> my_data = {'name': ['John Doe', 'Jane Doe', 'Mike Roth', 'Mark Wagner', 'David Scott'], ... 'title': ['developer', 'manager', 'developer', 'manager', 'developer']}
Convert it to dataframe object >>> df = pd.DataFrame(my_data, columns=['name','title']) >>> df.head() name title 0 John Doe developer 1 Jane Doe manager 2 Mike Roth developer 3 Mark Wagner manager 4 David Scott developer
use get_dummies panda method to break it out accordingly >>> df_title = pd.get_dummies(df['title'])
merge it to the original dataframe >>> df = pd.concat([df,df_title],axis=1)
Tada... that's our result >>> df.head() name title developer manager 0 John Doe developer 1.0 0.0 1 Jane Doe manager 0.0 1.0 2 Mike Roth developer 1.0 0.0 3 Mark Wagner manager 0.0 1.0 4 David Scott developer 1.0 0.0
It looks like the concept of information hiding is familiar
to a lot of developers, but from what I have seen it is viewed as more of “hide
the complex logic that I don’t care to see from me and just give me the object
to work with”
While this is certainly true, this is not the only
definition or implementation of information hiding…
Here is an example of how to make information hiding work
for you when you have something that can change in the future and make it
possible for you to localize the changes instead of refactoring entire code
base.
Let’s say that you are writing some type of program that
created new records and add them into the database. Each record would have
their own id that would be generated by your program.
A trivial approach is to get max record number in the
database, increase it by one and then add a new record. This would certainly
work, but here is a first glimpse of where information hiding can help… Instead
of incrementing the id inside of the block of code that adds new record create
a new method that would generate new id. This way, if in the future you would
want to change the logic, for instance, due to security concerns you don’t have
your ids to be sequential and you want to make them random. Also, you might
want to reuse deleted ids. All of this logic would be in one place! No need to
change this logic throughout your code base!
Well, that was a simple one… but here is another example!
Let’s say that you no longer allowed to have numerical ids… that means that if
you have snippets of code that compare objects simply on theirs id with
assumptions that they are numeric, this code would be broken.
So to change the id generation, that’s not a problem. You
can do that inside of one method.
Now, to make your code even more robust, you have to
implement comparable in your class that would make type of id irrelevant
outside of your class. All you have to do is to be able to specify logic
(numeric, alphanumeric, etc.) inside your one class and now you can have as
many comparisons throughout your code that would never have to change! All
thanks to information hiding that now would hide what type of id you have and
how it is compared.
Another example of where information hiding should be used are for methods that throw exceptions. For example, let's say that you use same class as before and need to get the id. The method that retrieves the id, shall not throw any low level exceptions like EOFException. This would expose the underlying implementation of your method... instead create higher level exception like DataNotFound that still in line with your domain object and provides little to its user in terms of its concrete implementation.
Hope you enjoyed this and like always ping me with questions
or feedback!
From http://www.codingpedia.org/ama/how-to-test-a-rest-api-from-command-line-with-curl/
How to test a REST api from command line with curl
If you want to quickly test your REST api from the command line, you can use curl. In this post I will present how to execute GET, POST, PUT, HEAD, DELETE HTTP Requests against a REST API. For the purpose of this blog post I will be using the REST api developed in my post Tutorial – REST API design and implementation in Java with Jersey and Spring
If in the first part of the blog post I will do a brief introduction to curl and what it can do (HTTP requests with options), in the second part I will “translate” the SOAPui test suite developed for the REST API tutorial to curl requests.
1.1. What is curl?
Curl is a command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, HTTP/2, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos…), file transfer resume, proxy tunneling and more.[1]
As mentioned, I will be using curl to simulate HEAD, GET, POST, PUT and DELETE request calls to the REST API.
1.2. HEAD requests
If you want to check if a resource is serviceable, what kind of headers it provides and other useful meta-information written in response headers, without having to transport the entire content, you can make a HEAD request. Let’s say I want to see what I would GET when requesting a Podcast resource. I would issue the following HEAD request with curl:
curl -i -X HEAD http://localhost:8888/demo-rest-jersey-spring/podcasts/1
Curl options
-i, --include – include protocol headers in the output (H/F)
-X, --request – specify request COMMAND (GET, PUT, DELETE…) to use
Response
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0631000000 --:--:--0:00:05 --:--:--0
HTTP/1.1200 OK
Date: Tue, 25 Nov 201412:54:56 GMT
Server: Jetty(9.0.7.v20131107)
Access-Control-Allow-Headers: X-extra-header
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Allow: OPTIONS
Content-Type: application/xml
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Vary: Accept-Encoding
Content-Length:631
Note the following headers
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, DELETE, PUT and
What I find a little bit intriguing is the response header Content-Type: application/xml, because I would have expected it to be application/json, since in the resource method defined with Jersey this should have taken precedence:
<?xml version="1.0" encoding="UTF-8"?><podcast><id>1</id><title>- The Naked Scientists Podcast - Stripping Down Science</title><linkOnPodcastpedia>http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science</linkOnPodcastpedia><feed>feed_placeholder</feed><description>The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home.</description><insertionDate>2014-10-29T10:46:02.00+0100</insertionDate></podcast>
Note that as expected from the HEAD request we get an xml document. Anyway we can force a JSON response by adding a header line to our curl request, setting the Accept HTTP header to application/json:
{"id":1,"title":"- The Naked Scientists Podcast - Stripping Down Science","linkOnPodcastpedia":"http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science","feed":"feed_placeholder","description":"The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home.","insertionDate":"2014-10-29T10:46:02.00+0100"}
If you want to have it displayed prettier, you can use the following command, provided you have Python installed on your machine.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
1007581007580069540 --:--:-- --:--:-- --:--:--6954[{"description": "The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home.",
"feed": "feed_placeholder",
"id": 1,
"insertionDate": "2014-10-29T10:46:02.00+0100",
"linkOnPodcastpedia": "http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science",
"title": "- The Naked Scientists Podcast - Stripping Down Science"},
{"description": "Quarks & Co: Das Wissenschaftsmagazin",
"feed": "http://podcast.wdr.de/quarks.xml",
"id": 2,
"insert
ionDate": "2014-10-29T10:46:13.00+0100",
"linkOnPodcastpedia": "http://www.podcastpedia.org/quarks",
"title": "Quarks & Co - zum Mitnehmen"}]
1.4. Curl request with multiple headers
As you’ve found out in my latest post, How to compress responses in Java REST API with GZip and Jersey, all the responses provided by the REST api are being compressed with GZip. This happens only if the client “suggests” that it accepts such encoding, by setting the following header Accept-encoding:gzip.
To achieve that you need to simply add another -H option with the corresponding value. Of course in this case you would get some unreadable characters in the content, if you do not redirect the response to a file:
* Adding handle:conn:0x28ddd80* Adding handle:send:0* Adding handle:recv:0*Curl_addHandleToPipeline:length:1* - Conn 0(0x28ddd80)send_pipe:1, recv_pipe:0
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
00000000 --:--:-- --:--:-- --:--:--0* About to connect() to proxy vldn680 port 19001(#0)* Trying 10.32.142.80...
* Connected to vldn680(10.32.142.80) port 19001(#0)> GET http://localhost:8888/demo-rest-jersey-spring/podcasts/ HTTP/1.1> User-Agent: curl/7.30.0> Host:localhost:8888> Proxy-Connection: Keep-Alive
> Accept:application/json
> Accept-encoding:gzip
>
< HTTP/1.1200 OK
< Date: Tue, 25 Nov 201416:17:02 GMT
* Server Jetty(9.0.7.v20131107) is not blacklisted
< Server: Jetty(9.0.7.v20131107)
< Content-Type: application/json
< Access-Control-Allow-Origin:*
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Encoding: gzip
< Content-Length:413
< Via:1.1vldn680:8888
<
{[data not shown]
1004131004130026470 --:--:-- --:--:-- --:--:--2647▒QKo▒0▒+▒▒g▒▒R▒+{▒V▒Pe▒▒؊c▒▒ n▒▒▒▒fæHH▒"▒▒g▒/?2▒eM▒gl▒a▒d
▒{=`7▒EÏ–▒▒c▒ZM
n8▒i▒▒▒}H▒▒i1▒3g▒▒▒▒▒ ;▒E▒0O▒n▒R*▒g/E▒▒n=▒▒▒▒)▒U▒▒▒lÕª▒Φ▒h▒6▒▒▒_>w▒▒-▒▒:▒▒▒!▒Bb▒Z▒▒tO▒N@'= |▒▒C▒f▒▒loØ ▒,T▒▒A▒4▒▒:▒l+<▒▒▒▒P▒3▒▒A▒lR
▒u▒a▒͓9hO #▒▒h▒i▒gq▒▒$▒▒|Ň ▒▒▒08>#▒0b!▒▒'▒G▒^▒Iﺬ.TU▒▒▒z▒\▒i^]e▒▒▒▒2▒▒▒֯▒▒?▒:/▒m▒▒▒▒▒Y▒h▒▒▒_䶙V▒+R▒WT▒0▒?f{▒▒▒▒&▒l▒▒Sk▒iÔ½~▒▒▒▒▒▒n▒▒▒▒_V]į▒
* Connection #0 to host vldn680 left intact
2. SOAPui test suite translated to curl requests
As mentioned, in this second part I will map to curl requests the SOAPui test suite presented here.
HTTP/1.1 204 No Content
Date: Tue, 25 Nov 2014 14:10:17 GMT
Server: Jetty(9.0.7.v20131107)Content-Type: text/html
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Via: 1.1 vldn680:8888
Content-Length: 0
2.1.2. POST new podcast without feed – 400 (BAD_REQUEST)
Request
curl -i -X POST -H "Content-Type:application/json" http://localhost:8888/demo-rest-jersey-spring/podcasts/ -d '{"title":"- The Naked Scientists Podcast - Stripping Down Science-new-title2","linkOnPodcastpedia":"http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science","description":"The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home."}'
Response
HTTP/1.1 400 Bad Request
Date: Tue, 25 Nov 2014 15:12:11 GMT
Server: Jetty(9.0.7.v20131107)Content-Type: application/json
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Content-Length: 271
Via: 1.1 vldn680:8888
Connection: close
{"status":400,"code":400,"message":"Provided data not sufficient for insertion","link":"http://www.codingpedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/","developerMessage":"Please verify that the feed is properly generated/set"}
2.1.3. POST new podcast correctly – 201 (CREATED)
Request
curl -i -X POST -H "Content-Type:application/json" http://localhost:8888/demo-rest-jersey-spring/podcasts/ -d '{"title":"- The Naked Scientists Podcast - Stripping Down Science","linkOnPodcastpedia":"http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science","feed":"feed_placeholder","description":"The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home."}'
Response
HTTP/1.1 201 Created
Location: http://localhost:8888/demo-rest-jersey-spring/podcasts/2
Content-Type: text/html
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Content-Length: 60
Server: Jetty(9.0.7.v20131107)A new podcast has been created AT THE LOCATION you specified
2.1.4. POST same podcast as before to receive – 409 (CONFLICT)
Request
curl -i -X POST -H "Content-Type:application/json" http://localhost:8888/demo-rest-jersey-spring/podcasts/ -d '{"title":"- The Naked Scientists Podcast - Stripping Down Science","linkOnPodcastpedia":"http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science","feed":"feed_placeholder","description":"The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home."}'
Response
HTTP/1.1 409 Conflict
Date: Tue, 25 Nov 2014 15:58:39 GMT
Server: Jetty(9.0.7.v20131107)Content-Type: application/json
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Content-Length: 300
{"status":409,"code":409,"message":"Podcast with feed already existing in the database with the id 1","link":"http://www.codingpedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/","developerMessage":"Please verify that the feed and title are properly generated"}
2.1.5. PUT new podcast at location – 201 (CREATED)
Request
curl -i -X PUT -H "Content-Type:application/json" http://localhost:8888/demo-rest-jersey-spring/podcasts/2 -d '{"id":2,"title":"Quarks & Co - zum Mitnehmen","linkOnPodcastpedia":"http://www.podcastpedia.org/quarks","feed":"http://podcast.wdr.de/quarks.xml","description":"Quarks & Co: Das Wissenschaftsmagazin"}'
Response
HTTP/1.1 201 Created
Location: http://localhost:8888/demo-rest-jersey-spring/podcasts/2
Content-Type: text/html
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Content-Length: 60
Server: Jetty(9.0.7.v20131107)A new podcast has been created AT THE LOCATION you specified
< HTTP/1.1200 OK
< Content-Type: application/json
< Access-Control-Allow-Origin:*
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length:419* Server Jetty(9.0.7.v20131107) is not blacklisted
< Server: Jetty(9.0.7.v20131107)
<
0419000000 --:--:-- --:--:-- --:--:--0{[data not shown]
*STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)1004191004190060440 --:--:-- --:--:-- --:--:--6983* Connection #0 to host localhost left intact* Expire cleared
[{"feed": "http://podcast.wdr.de/quarks.xml",
"id": 1,
"insertionDate": "2014-06-05T22:35:34.00+0200",
"linkOnPodcastpedia": "http://www.podcastpedia.org/quarks",
"title": "Quarks & Co - zum Mitnehmen"},
{"feed": "http://www.dayintechhistory.com/feed/podcast-2",
"id": 2,
"insertionDate": "2014-06-05T22:35:34.00+0200",
"linkOnPodcastpedia": "http://www.podcastpedia.org/podcasts/766/Day-in-Tech-History",
"title": "Day in Tech History"}]
2.3. Update podcast resource
2.3.1. PUT not “complete” podcast for FULL update – 400 (BAD_REQUEST)
Request
curl -v -H "Content-Type:application/json" -X PUT http://localhost:8888/demo-rest-jersey-spring/podcasts/2 -d '{"id":2, "title":"Quarks & Co - zum Mitnehmen","linkOnPodcastpedia":"http://www.podcastpedia.org/quarks","feed":"http://podcast.wdr.de/quarks.xml"}'
Response
< HTTP/1.1400 Bad Request
< Content-Type: application/json
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length: 290* Server Jetty(9.0.7.v20131107)isnot blacklisted
< Server: Jetty(9.0.7.v20131107)
<
* STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)* Connection #0 to host localhost left intact* Expire cleared
{"status":400,"code":400,"message":"Please specify all properties for Full UPDATE","link":"http://www.codingpedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/","developerMessage":"required properties - id, title, feed, lnkOnPodcastpedia, description"}
2.3.2. PUT podcast for FULL update – 200 (OK)
Request
$ curl -v -H "Content-Type:application/json" -X PUT http://localhost:8888/demo-rest-jersey-spring/podcasts/2 -d '{"id":2, "title":"Quarks & Co - zum Mitnehmen","linkOnPodcastpedia":"http://www.podcastpedia.org/quarks","feed":"http://podcast.wdr.de/quarks.xml", "description":"Quarks & Co: Das Wissenschaftsmagazin"}'
Response
< HTTP/1.1200 OK
< Location: http://localhost:8888/demo-rest-jersey-spring/podcasts/2
< Content-Type: text/html
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length: 86*Server Jetty(9.0.7.v20131107)is not blacklisted
< Server: Jetty(9.0.7.v20131107)
<
* STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)* Connection #0 to host localhost left intact* Expire cleared
The podcast you specified has been fully updated created AT THE LOCATION you specified
2.3.3. POST (partial update) for not existent podcast – 404 (NOT_FOUND)
Request
$ curl -v -H "Content-Type:application/json" -X POST http://localhost:8888/demo-rest-jersey-spring/podcasts/3 -d '{"title":"Quarks & Co - zum Mitnehmen - GREAT PODCAST"}'| python -m json.tool
Response
< HTTP/1.1404 Not Found
< Content-Type: application/json
< Access-Control-Allow-Origin:*
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length:306* Server Jetty(9.0.7.v20131107) is not blacklisted
< Server: Jetty(9.0.7.v20131107)
<
{[data not shown]
*STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)1003611003061005590691630 --:--:-- --:--:-- --:--:--13304* Connection #0 to host localhost left intact* Expire cleared
{"code": 404,
"developerMessage": "Please verify existence of data in the database for the id - 3",
"link": "http://www.codingpedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/",
"message": "The resource you are trying to update does not exist in the database",
"status": 404}
2.3.4. POST (partial update) podcast – 200 (OK)
Request
$ curl -v -H "Content-Type:application/json" -X POST http://localhost:8888/demo-rest-jersey-spring/podcasts/2 -d '{"title":"Quarks & Co - zum Mitnehmen - GREAT PODCAST"}'
Response
< HTTP/1.1200 OK
< Content-Type: text/html
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length: 55* Server Jetty(9.0.7.v20131107)isnot blacklisted
< Server: Jetty(9.0.7.v20131107)
<
* STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)* Connection #0 to host localhost left intact* Expire cleared
The podcast you specified has been successfully updated
2.4. DELETE resource
2.4.1. DELETE second inserted podcast – 204 (NO_CONTENT)
< HTTP/1.1404 Not Found
< Content-Type: application/json
< Access-Control-Allow-Origin:*
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length:306* Server Jetty(9.0.7.v20131107) is not blacklisted
< Server: Jetty(9.0.7.v20131107)
<
{[data not shown]
*STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)1003061003060089160 --:--:-- --:--:-- --:--:--13304* Connection #0 to host localhost left intact* Expire cleared
{"code": 404,
"developerMessage": "Verify the existence of the podcast with the id 2 in the database",
"link": "http://www.codingpedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/",
"message": "The podcast you requested with id 2 was not found in the database",
"status": 404}
2.5. Bonus operations
2.5.1. Add podcast from application form urlencoded
< HTTP/1.1201 Created
< Location: http://localhost:8888/demo-rest-jersey-spring/podcasts/null
< Content-Type: text/html
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
< Vary: Accept-Encoding
< Content-Length: 81* Server Jetty(9.0.7.v20131107)isnot blacklisted
< Server: Jetty(9.0.7.v20131107)
<
* STATE: PERFORM => DONE handle 0x600056180; line 1626(connection #0)* Connection #0 to host localhost left intact* Expire cleared
A new podcast/resource has been created at /demo-rest-jersey-spring/podcasts/null