2016-07-04 6 views
6

फीनिक्स के साथ कुछ एपीआई बनाया गया है, एपीआई जेएसओएन के साथ काम करता है।फीनिक्स अनुरोध के लिए JSON एन्कोडिंग को कैसे लागू करें?

लेकिन, जब आप इसका परीक्षण करते हैं और curl के साथ JSON भेजते हैं तो यह विफल हो जाता है क्योंकि फीनिक्स JSON के रूप में अनुरोध को पार्स नहीं करता है। आपको application/json हेडर को curl में स्पष्ट रूप से जोड़ने की आवश्यकता है। मैं इसे और अधिक मजबूत बनाना चाहता हूं और जेनॉन के रूप में सभी अनुरोधों को हमेशा पार्स करने के लिए फीनिक्स को बताऊंगा।

क्या फीनिक्स को हमेशा जेएसओएन के रूप में अनुरोधों का इलाज करने और जेएसओएन के रूप में विश्लेषण करने का कोई तरीका है?

अद्यतन

मैं रूटर में निम्न कोड के साथ प्लग का उपयोग करने के अनुरोध हेडर स्थापित करने के लिए के रूप में @AbM का सुझाव दिया, करने की कोशिश की:

def set_format conn, format do Plug.Conn.put_private conn, :phoenix_format, format end 

def put_req_header conn, {key, value} do Plug.Conn.put_req_header conn, key, value end 

pipeline :api do 
    plug :put_req_header, {"accept", "application/json"} 
    plug :put_req_header, {"content-type", "application/json"} 
    plug :set_format, "json" 
    plug :accepts, ["json"] 
end 

अनुरोध कर्ल के साथ किया गया है

curl -X POST http://localhost:4000/api/upload -d '{"key": "value"}'      

कनेक्शन इस तरह दिखता है:

%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, 
before_send: [#Function<1.93474994/1 in Plug.Logger.call/2>, 
    #Function<0.119481890/1 in Phoenix.LiveReloader.before_send_inject_reloader/1>], 
body_params: %{"{\"key\": \"value\"}" => nil}, 
cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, 
host: "localhost", method: "POST", owner: #PID<0.483.0>, 
params: %{"{\"key\": \"value\"}" => nil}, 
path_info: ["api", "upload"], peer: {{127, 0, 0, 1}, 58408}, 
port: 4000, 
private: %{App.Router => {[], %{}}, 
    :phoenix_action => :upload, 
    :phoenix_controller => ApiController, :phoenix_endpoint => App.Endpoint, 
    :phoenix_format => "json", :phoenix_layout => {LayoutView, :app}, 
    :phoenix_pipelines => [:api], 
    :phoenix_route => #Function<8.59735990/1 in App.Router.match_route/4>, 
    :phoenix_router => App.Router, :phoenix_view => ApiView, 
    :plug_session_fetch => #Function<1.89562996/1 in Plug.Session.fetch_session/1>}, 
query_params: %{}, 
query_string: "", remote_ip: {127, 0, 0, 1}, 
req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, 
req_headers: [{"user-agent", "curl/7.37.1"}, {"host", "localhost:4000"}, 
    {"accept", "application/json"}, {"content-length", "16"}, 
    {"content-type", "application/json"}], 
request_path: "/api/upload", resp_body: nil, resp_cookies: %{}, 
resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, 
    {"x-request-id", "xxx"}], scheme: :http, 
script_name: [], 
secret_key_base: "xxx", 
state: :unset, status: nil} 

यह काम करता है अगर मैं -H "Content-Type: application/json" पैरामीटर को कर्ल में जोड़ता हूं, इसके बिना यह काम नहीं करता है।

+0

होगा [ 'put_req_header (कोन," स्वीकार "," आवेदन/json ")' के साथ अपने रूटर में एक प्लग जोड़ने ] (https://hexdocs.pm/plug/Plug.Conn.html#put_req_header/3) अपनी समस्या का समाधान करें? – AbM

+0

नहीं, यह काम नहीं कर रहा है :( –

+0

क्या आप थोड़ा और विस्तार कर सकते हैं। शायद अपने राउटर.एक्स – AbM

उत्तर

1

अगर कोई इसके लिए Google करेगा और इस तरह के व्यवहार को लागू करना चाहता है।

lib/%APP_NAME%/endpoint.ex

plug Plug.Head 

# add custom plug 
plug :set_format, "json" 

यह निर्धारित करें:

defp set_format(conn, format) do 
    if Regex.match?(~r/^api.*/, conn.host) do 
     Plug.Conn.put_private conn, :phoenix_format, format 
    else 
     conn 
    end 
    end 

इस उदाहरण में हम ऐसे ही करने के लिए गंदा हैक किस उप डोमेन के लिए JSON प्रारूप लागू करेंगे api

यह सिफारिश नहीं किया गया लेकिन फीनिक्स किसी भी समय एचटीएमएल लागू करने के बाद से यह हैक हास्यास्पद व्यवहार को ठीक करता है उर की तरह: के लिए Elixir.Phoenix.Router.NoRouteError pipeline :api 404.html के बजाय 404.json दिखाने के लिए

संबंधित मुद्दे