Fazer pedidos personalizados
até agora aprendemos a fazer o simples pedidos de HTTP, mas não se concentrar demais em pedido de personalização, como configuração personalizada cabeçalhos de solicitação ou de tomada de PUT
PATCH
e DELETE
(e outros) pedidos de HTTP.
http.Estrutura do pedido
o http.Request
struct configura o pedido a ser enviado., Get
Post
e outros métodos expostos por *http.Client
realmente construir http.Request
objeto internamente para enviar o pedido.
Esta estrutura tem vários campos para configurar a ligação TLS, a ligação keep-alive, os dados do formulário e outras configurações, mas os seguintes campos são configuração mínima com que podemos trabalhar.
💡 Você pode ler mais sobre
Request
struct a partir daqui.,
The*http.Request
struct implementa muitos métodos para modificar o objeto de pedido antes de ser enviado. O método *Request.AddCookie
adiciona um cookie sobre o objeto pedido e *Request.SetBasicAuth
define o cabeçalho de autorização básica a pedido. Você pode explorar estes métodos a partir daqui.
Uma vez que construamos um objeto de pedido, precisamos fazer um pedido com este objeto de pedido manualmente. Para isso, precisamos usar o método *Client.Do
. Uma vez que Go fornece http.DefaultClient
, podemos usar isso para fazer um pedido.,
func (c *Client) Do(req *Request) (*Response, error)
In the above example, we are first creating a *url.URL
object from a URL string by using url.Parse
function. Since Request.URL
field should be an object of type *url.URL
, this step is necessary.,
O corpo do pedido armazenado em Request.Body
campo deve ser um objeto que implementa io.ReadCloser
(interface de um grupo de io.Reader
e io.Closer
interfaces). strings.NewReader
retorna um io.Reader
objeto e ioutil.NopCloser
função adiciona Close()
método io.Reader
objeto.
Close
método adicionado por NopCloser
função não faz nada, ele simplesmente retorna um nil
erro., O corpo do pedido é fechado para I/O através deste Close()
método call quando o pedido é enviado. Em um caso de uso no mundo real, você deve implementar Close
método corretamente para desativar I / O no corpo do pedido.
também inicializámos o campo Header
com alguns cabeçalhos de pedido inicial. Para enviar o pedido, Estamos usando o método DefaultClient.Do
que retorna a resposta da rede e um non-nil
Erro se o pedido falhar.,
🌶 go run go-http-client.go
status: 200
body: {"status":"success","data":{"name":"test","salary":"123","age":"23","id":53}}
eu concordo, o envio de uma solicitação personalizado parece um pouco complicado, mas podemos usar o http.NewRequest
função para criar *http.Request
objeto a partir de alguns valores simples que tem a seguinte sintaxe.
func NewRequest(method, url string, body io.Reader) (*Request, error)
Esta função retorna um *http.Request
e o non-nil
erro no caso de alguns valores dos argumentos não são válidos. Semethod
argumento está vazio, pedido é assumido., We can add headers to the returned *Request
object.
The program above returns the same response as the earlier example., Mesmo que reqBody
não implementa io.Closer
interface, ele deverá implementar um válido Close
método que desactiva de e/S, outro lugar, Ir adiciona um não-op método fechar sobre ele, usando o ioutil.NopCloser
função.
http.A estrutura do cliente
o http.Client
estrutura cria um cliente HTTP com alguma configuração que pode enviar pedidos HTTP. The http.DefaultClient
is a pointer to an empty http.Client
object which exposes a default HTTP client.,
var DefaultClient = &http.Client{}
Como vimos antes, o *http.Client
implementa Get
Post
PostForm
Head
e Do
métodos. Vejamos como se parece o tipo de estrutura http.Client
.
type Client struct {
// mechanism by which individual HTTP requests are made
Transport RoundTripper
// specifies the policy for handling redirects
CheckRedirect func(req *Request, via *Request) error// specifies the cookie jar
Jar CookieJar
// specifies a time limit for requests
Timeout time.Duration
}
The Transport
field an object that implements the RoundTrip
method. Este objeto é responsável por executar um único pedido HTTP e retornar uma resposta., Se este valor de campo é nil
http.DefaultTransport
do tipo *http.Transport
é usado. Na maioria dos casos, este valor padrão é bom o suficiente para nós.
O campoCheckRedirect
é uma função que verifica se o redirecionamento exigido por uma resposta precisa ser seguido. If this value is nil
, the default policy of maximum 10
redirects is used.
The argument is the newest request andvia
argument contains the older request (in old first order)., Se esta função retorna um erro non-nil
, a tentativa de redirecionamento é bloqueada. Verifique esta documentação para saber mais sobre como a resposta é devolvida e os tipos de erro.
O campo Jar
especifica um mecanismo para adicionar cookies nos pedidos HTTP enviados e cookies de cache das respostas recebidas. Este frasco de cookies é consultado para cada pedido de saída e redirecionamento.
Se este valor for nil
, os cookies só são enviados se forem especificados a pedido (e copiados para pedidos redireccionados)., No caso de um pedido redirecionado, Cookie jar pode alterar os valores do cookie. Você pode usar o pacote net/http/cookiejar
para criar o seu frasco de cookies personalizado.
O campoTimeout
especifica o prazo antes do qual a resposta deve ser lida. Se o valor do campo for 0
o que significa que não há tempo-limite implementado pelo cliente HTTP. Este valor indica o tempo até que a resposta final seja totalmente lida, o que inclui todos os redirecionamentos e leitura da resposta.,
⚠️ como o valor padrão de
Timeout
campo é0
, pode ser perigoso em algumas situações em que um serviço mal-intencionado nunca envia uma resposta, esgotando a sua largura de banda, e causar outros problemas. Assim, certifique-se de adicionar algum tempo-limite para cada pedido que se origina de sua máquina.
Para verificar se o erro retornado por *Client.Get
(ou qualquer outro método) é devido ao tempo de espera, devemos verificar err.Timeout()
valor., Se o tempo-limite ocorrer durante a leitura do corpo de resposta, ele retornará um erro.
vamos criar um novo cliente com um pequeno valor-limite e enviar um simples HTTP pedido. Vamos definir o valor de tempo-limite 100 milliseconds
e como há uma alta probabilidade de tempo-limite de pedido, também vamos verificar para um erro de tempo-limite.,
In the example above, we have created an HTTP client with a timeout of 100ms
. Since Get
, Post
and other methods are implemented by the pointer of http.Client
type, the client
is a pointer.,
Desde de erro retornado por Get
método (e outros métodos) é sempre do tipo de *url.Error
tipo, precisamos extrair esse valor concreto a partir de err
qual é o tipo de error
interface.
Quando o erro ocorre devido a um tempo limite, o *Error.Temporary()
método retorna true
. E a partir do resultado abaixo, podemos ver que o erro retornado pelo método Get
é de fato por causa de um tempo-limite.