Reputation: 35
I'm trying to filter out this response body that I'm getting using Enum.filter
and String.match
'ing the response body. How would I go about it?
iex(15)> response = HTTPoison.get!("http://127.0.0.1:8081/service/rest/v1/repositories")
%HTTPoison.Response{
body: "[ {\n \"name\" : \"maven-snapshots\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-central\",\n \"format\" : \"maven2\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n }\n }\n}, {\n \"name\" : \"nuget-group\",\n \"format\" : \"nuget\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget.org-proxy\",\n \"format\" : \"nuget\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n }\n }\n}, {\n \"name\" : \"maven-releases\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget-hosted\",\n \"format\" : \"nuget\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-public\",\n \"format\" : \"maven2\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n \"attributes\" : { }\n}, {\n \"name\" : \"Taskmaster1\",\n \"format\" : \"docker\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n \"attributes\" : { }\n} ]",
headers: [
{"Date", "Sun, 27 Oct 2019 20:39:44 GMT"},
{"Server", "Nexus/3.19.1-01 (OSS)"},
{"X-Content-Type-Options", "nosniff"},
{"Content-Type", "application/json"},
{"Content-Length", "1411"}
],
request: %HTTPoison.Request{
body: "",
headers: [],
method: :get,
options: [],
params: %{},
url: "http://127.0.0.1:8081/service/rest/v1/repositories"
},
request_url: "http://127.0.0.1:8081/service/rest/v1/repositories",
status_code: 200
}
This is the error I receive:
iex(16)> Enum.filter(response.body, fn {key, _} -> String.match?(key, ~r/\A\n \"format\" : \"docker\"\z/i) end)
** (Protocol.UndefinedError) protocol Enumerable not implemented for "[ {\n \"name\" : \"maven-snapshots\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-central\",\n \"format\" : \"maven2\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n }\n }\n}, {\n \"name\" : \"nuget-group\",\n \"format\" : \"nuget\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget.org-proxy\",\n \"format\" : \"nuget\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n }\n }\n}, {\n \"name\" : \"maven-releases\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget-hosted\",\n \"format\" : \"nuget\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-public\",\n \"format\" : \"maven2\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n \"attributes\" : { }\n}, {\n \"name\" : \"Taskmaster1\",\n \"format\" : \"docker\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n \"attributes\" : { }\n} ]" of type BitString. This protocol is implemented for the following type(s): Ecto.Adapters.SQL.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashSet, Range, Map, Function, List, Stream, Date.Range, HashDict, GenEvent.Stream, MapSet, File.Stream, IO.Stream
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:141: Enumerable.reduce/3
(elixir) lib/enum.ex:3023: Enum.filter/2
It works with the headers, but not for the body:
iex(16)> response = HTTPoison.get!("http://127.0.0.1:8081/service/rest/v1/repositories")
%HTTPoison.Response{
body: "[ {\n \"name\" : \"maven-snapshots\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-central\",\n \"format\" : \"maven2\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n }\n }\n}, {\n \"name\" : \"nuget-group\",\n \"format\" : \"nuget\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget.org-proxy\",\n \"format\" : \"nuget\",\n \"type\" : \"proxy\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n \"attributes\" : {\n \"proxy\" : {\n \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n }\n }\n}, {\n \"name\" : \"maven-releases\",\n \"format\" : \"maven2\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n \"attributes\" : { }\n}, {\n \"name\" : \"nuget-hosted\",\n \"format\" : \"nuget\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n \"attributes\" : { }\n}, {\n \"name\" : \"maven-public\",\n \"format\" : \"maven2\",\n \"type\" : \"group\",\n \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n \"attributes\" : { }\n}, {\n \"name\" : \"Taskmaster1\",\n \"format\" : \"docker\",\n \"type\" : \"hosted\",\n \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n \"attributes\" : { }\n} ]",
headers: [
{"Date", "Sun, 27 Oct 2019 20:47:30 GMT"},
{"Server", "Nexus/3.19.1-01 (OSS)"},
{"X-Content-Type-Options", "nosniff"},
{"Content-Type", "application/json"},
{"Content-Length", "1411"}
],
request: %HTTPoison.Request{
body: "",
headers: [],
method: :get,
options: [],
params: %{},
url: "http://127.0.0.1:8081/service/rest/v1/repositories"
},
request_url: "http://127.0.0.1:8081/service/rest/v1/repositories",
status_code: 200
}
iex(17)> Enum.filter(response.headers, fn {key, _} -> String.match?(key, ~r/\Adate\z/i) end)
[{"Date", "Sun, 27 Oct 2019 20:47:30 GMT"}]
Upvotes: 0
Views: 700
Reputation: 23164
The body is a string, so Enum
functions don't work with it. It seems to be some kind of JSON, so you probably want to parse it into a datastructure first. You can do that using several elixir libraries, for example using Poison:
response.body
|> Poison.decode!()
|> Enum.filter(fn item ->
item["format"] == "docker"
end)
|> IO.inspect()
produces:
[
%{
"attributes" => %{},
"format" => "docker",
"name" => "Taskmaster1",
"type" => "hosted",
"url" => "http://127.0.0.1:8081/repository/Taskmaster1"
}
]
Upvotes: 0
Reputation: 23091
First, a better way to filter the header is like this:
Enum.filter(response.headers, &match?({"Date", _}, &1))
Output:
[{"Date", "Sun, 27 Oct 2019 20:47:30 GMT"}]
For the body, you should decode it from JSON first. You need to pick a JSON library and add it to mix.exs
. I'm using Jason. Then you can match in the same way as above:
Jason.decode!(request.body) |> Enum.filter(&match?(%{"name" => "maven-central"}, &1))
Output:
[
%{
"attributes" => %{
"proxy" => %{"remoteUrl" => "https://repo1.maven.org/maven2/"}
},
"format" => "maven2",
"name" => "maven-central",
"type" => "proxy",
"url" => "http://127.0.0.1:8081/repository/maven-central"
}
]
Upvotes: 1