2014-04-01 6 views
7

Sto facendo una dimostrazione di concetto per dimostrare come potremmo implementare 3scale nel nostro stack. In un esempio, desidero eseguire alcune operazioni POST per la manipolazione del corpo per creare una facciata API che mappi quello che potrebbe essere un formato API legacy a un nuovo interno. Per esempio. cambiare qualcosa comeCome posso manipolare il corpo JSON di una richiesta POST utilizzando Nginx e Lua?

{ "foo" : "bar" , "deprecated" : true } 

in

{ "FOO" : "bar" } 

Il Lua module docs for content_by_lua, che sembra il metodo più appropriato dire

Non usare questa direttiva e di altre direttive di gestione dei contenuti nella stessa posizione. Ad esempio, questa direttiva e la direttiva proxy_pass non devono essere utilizzate nella stessa posizione.

La mia comprensione è che content_by_lua è un gestore di contenuto come proxy_pass, solo uno dei quali può essere utilizzato per posizione.

Non credo che ci sia alcun modo per rimuovere proxy_pass come questo è la base di come funziona dei proxy, quindi è possibile catturare la richiesta in un luogo separato, utilizzare content_by_lua, quindi passare alla posizione attuazione proxy_pass oppure esiste un altro metodo come rewrite_by_lua che è più appropriato?


Se aiuta chiunque altro, ho aggiunto la seguente funzione (il mio primo pezzo di Lua) che rimuove il parametro user_key che 3scale richiede l'autorizzazione, ma non è valido per la nostra API se inoltrati:

function remove_user_key() 
    ngx.req.read_body() 
    -- log the original body so we can compare to the new one later 
    local oldbody = ngx.req.get_body_data() 
    log(oldbody) 
    -- grab the POST parameters as a table 
    local params = ngx.req.get_post_args() 

    -- build up the new JSON string 
    local newbody = "{" 

    for k,v in pairs(params) do 
    -- add all the params we want to keep 
    if k ~= "user_key" then 
     log("adding"..k.." as "..v) 
     newbody = newbody..'"'..k..'":"'..v..'",' 
    else 
     log("not adding user_key") 
    end 
    end 
    --remove the last trailing comma before closing this off 
    newbody = string.sub(newbody, 0, #newbody-1) 
    newbody = newbody.."}" 

    ngx.req.set_body_data(newbody) 
    log(newbody) 
end 

if ngx.req.get_method() == "POST" then 
    remove_user_key() 
end 

risposta

4

io suggerisco di utilizzare access_by_lua
in nginx.conf

 
location/{ 
       #host and port to fastcgi server 
       default_type text/html; 
       set $URL "http://$http_host$request_uri"; 
       access_by_lua_file /home/lua/cache.lua; 
       proxy_pass http://$target; 
       ------- 
       --------- 

nel file di cache.lua si può fare qualcosa di simile:

 
if ngx.req.get_method() == "POST" then 
    -- check if request method is POST 
    -- implement your logic 
    return 
end 
4

Aggiungendo a ciò Prashant già detto: quando si scaricano i file di configurazione Nginx da 3scale si noterà che c'è un file Lua incluso. Questo file è già stato chiamato da access_by_lua_file.

Quel file sarebbe a mio parere il posto migliore per aggiungere il codice di manipolazione del corpo. Verrà eseguito per ogni richiesta prima che venga inviato lo proxy_pass al server API.

Inoltre, questo è davvero un buon approfondito articolo blog su come portare a termine la trasformazione diversa alle vostre richieste utilizzando Lua all'interno Nginx: http://tech.3scale.net/2013/01/09/augment-your-api-without-touching-it/

+0

Grazie, in effetti ho aggiunto il codice che ho postato sopra in fondo al file che hai menzionato quando ho notato che 'access_by_lua_file' era già stato chiamato. Il collegamento – Jesse

1

Recentemente ho avuto di manipolare a monte in base al valore JSON in richiesta post e mi trovato utile: NGINX LUA and JSON

È la configurazione di base ma dà un'idea di come farlo.

+4

non funziona più – w00t