Ho scritto una semplice API REST (semplicemente imparando) usando Go
e sto chiamando usando python requests
. Ho due metodi, "update_x", che aggiorna il valore della risorsa, "get_x_times_n" che ottiene il valore della risorsa. Logicamente, penserei che ho bisogno (e posso solo usare) put
per "update_x" e get
per "get_x_times_n". Tuttavia, posso facilmente implementare un metodo, in modo tale che possa chiamare "get_x_times_n" utilizzando put
.
Ecco il mio Go
code:
package main
import (
"fmt"
"log"
"io"
"io/ioutil"
"net/http"
"encoding/json"
"strconv"
)
func main() {
my_resource := MyResource{x: 0}
http.HandleFunc("/update_x", my_resource.update_x)
http.HandleFunc("/get_x_times_n", my_resource.get_x_times_n)
http.HandleFunc("/get_x_times_n_wierd", my_resource.get_x_times_n_wierd)
http.ListenAndServe("localhost:8000", nil)
}
type MyResource struct {
x int
}
func (mr *MyResource) update_x(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(io.Reader(r.Body))
if err != nil {
panic(err)
}
if err := r.Body.Close(); err != nil {
panic(err)
}
var delta int
err = json.Unmarshal(body, &delta)
if err != nil {
panic(err)
}
mr.x += delta
}
func (mr *MyResource) get_x_times_n(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
panic(err)
}
log.Println(r.Form)
n_str := r.Form["n"][0]
n, err := strconv.Atoi(n_str)
if err != nil {
panic(err)
}
result := mr.x * n
fmt.Fprint(w, result)
}
func (mr *MyResource) get_x_times_n_wierd(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.Body)
body, err := ioutil.ReadAll(io.Reader(r.Body))
if err != nil {
panic(err)
}
if err := r.Body.Close(); err != nil {
panic(err)
}
var n int
err = json.Unmarshal(body, &n)
if err != nil {
panic(err)
}
result := mr.x * n
fmt.Fprint(w, result)
}
Ed ecco la mia sessione Python:
In [51]: import requests
In [52]: r = requests.put("http://localhost:8000/update_x", data='5')
In [53]: r = requests.get("http://localhost:8000/get_x_times_n", params={"n": 5})
In [54]: r.content
Out[54]: '25'
In [55]: r = requests.put("http://localhost:8000/get_x_times_n_wierd", data="5")
In [56]: r.content
Out[56]: '25'
Posso capire perché questo sta accadendo, dal momento che in entrambi i metodi ho r *http.Request
, posso passare qualsiasi dato che voglio. E anche in entrambi i metodi ho accesso a w http.ResponseWriter
, posso scrivere tutto ciò che voglio.
La mia domanda è: cosa sto sbagliando? Sto solo abusando di requests
quando utilizzo l'API? Ho impostato la mia API completamente sbagliato? (Se l'API è stata impostata correttamente, qualcosa di simile non sarebbe consentito?). O entrambi? O forse qualcos'altro?