Contexto HTTP
Uma nova instância da classe Contexto HTTP é gerada para cada solicitação HTTP e passada para o manipulador de rota, middleware e manipulador de exceção.
O Contexto HTTP contém todas as informações que você pode precisar relacionadas a uma solicitação HTTP. Por exemplo:
- Propriedade ctx.request.
- Propriedade ctx.response.
- Propriedade ctx.auth.
- Propriedade ctx.bouncer.
- E assim por diante.
Em poucas palavras, o contexto é um armazenamento específico de solicitação que contém todas as informações para a solicitação em andamento.
Obtendo acesso ao contexto HTTP
O contexto HTTP é passado por referência ao manipulador de rota, middleware e manipulador de exceção, e você pode acessá-lo da seguinte maneira.
Manipulador de rota
O manipulador de roteador recebe o contexto HTTP como o primeiro parâmetro.
import router from '@adonisjs/core/services/router'
router.get('/', (ctx) => {
console.log(ctx.inspect())
})
// Propriedades desestruturada
import router from '@adonisjs/core/services/router'
router.get('/', ({ request, response }) => {
console.log(request.url())
console.log(request.headers())
console.log(request.qs())
console.log(request.body())
response.send('hello world')
response.send({ hello: 'world' })
})
Método do controlador
O método do controlador (semelhante ao manipulador do roteador) recebe o contexto HTTP como o primeiro parâmetro.
import { HttpContext } from '@adonisjs/core/http'
export default class HomeController {
async index({ request, response }: HttpContext) {
}
}
Classe do middleware
O método handle
da classe do middleware recebe o contexto HTTP como o primeiro parâmetro.
import { HttpContext } from '@adonisjs/core/http'
export default class AuthMiddleware {
async handle({ request, response }: HttpContext) {
}
}
Classe manipuladora de exceções
Os métodos handle
e report
da classe manipulador de exceções global recebem o contexto HTTP como o segundo parâmetro. O primeiro parâmetro é a propriedade error
.
import {
HttpContext,
HttpExceptionHandler
} from '@adonisjs/core/http'
export default class ExceptionHandler extends HttpExceptionHandler {
async handle(error: unknown, ctx: HttpContext) {
return super.handle(error, ctx)
}
async report(error: unknown, ctx: HttpContext) {
return super.report(error, ctx)
}
}
Injetando contexto HTTP usando injeção de dependência
Se você usar injeção de dependência em todo o seu aplicativo, poderá injetar o contexto HTTP em uma classe ou método por meio de dicas de tipo da classe HttpContext
.
ATENÇÃO
Certifique-se de que o middleware #middleware/container_bindings_middleware
esteja registrado dentro do arquivo kernel/start.ts
. Este middleware é necessário para resolver valores específicos da solicitação (por exemplo, a classe HttpContext) do contêiner.
// app/services/user_service.ts
import { inject } from '@adonisjs/core'
import { HttpContext } from '@adonisjs/core/http'
@inject()
export default class UserService {
constructor(protected ctx: HttpContext) {}
all() {
// implementação do método
}
}
Para que a resolução automática de dependências funcione, você deve injetar o UserService
dentro do seu controlador. Lembre-se, o primeiro argumento para um método do controlador sempre será o contexto, e o restante será injetado usando o contêiner IoC.
import { inject } from '@adonisjs/core'
import { HttpContext } from '@adonisjs/core/http'
import UserService from '#services/user_service'
export default class UsersController {
@inject()
index(ctx: HttpContext, userService: UserService) {
return userService.all()
}
}
Isso é tudo! O UserService
agora receberá automaticamente uma instância da solicitação HTTP em andamento. Você pode repetir o mesmo processo para dependências aninhadas também.
Acessando o contexto HTTP de qualquer lugar dentro do seu aplicativo
A injeção de dependência é uma maneira de aceitar o contexto HTTP como um construtor de classe ou uma dependência de método e, então, confiar no contêiner para resolvê-lo para você.
No entanto, não é um requisito difícil reestruturar seu aplicativo e usar a injeção de dependência em todos os lugares. Você também pode acessar o contexto HTTP de qualquer lugar dentro do seu aplicativo usando o Armazenamento local assíncrono fornecido pelo Node.js.
Temos um guia dedicado sobre como o armazenamento local assíncrono funciona e como o AdonisJS o usa para fornecer acesso global ao contexto HTTP.
No exemplo a seguir, a classe UserService
usa o método HttpContext.getOrFail
para obter a instância do contexto HTTP para a solicitação em andamento.
// app/services/user_service.ts
import { HttpContext } from '@adonisjs/core/http'
export default class UserService {
all() {
const ctx = HttpContext.getOrFail()
console.log(ctx.request.url())
}
}
O bloco de código a seguir mostra o uso da classe UserService
dentro do UsersController
.
import { HttpContext } from '@adonisjs/core/http'
import UserService from '#services/user_service'
export default class UsersController {
index(ctx: HttpContext) {
const userService = new UserService()
return userService.all()
}
}
Propriedades do contexto HTTP
A seguir está a lista de propriedades que você pode acessar por meio do contexto HTTP. À medida que você instala novos pacotes, eles podem adicionar propriedades adicionais ao contexto.
ctx.request
Referência a uma instância da classe HTTP Request.
ctx.response
Referência a uma instância da classe HTTP Response.
ctx.logger
Referência a uma instância de logger criada para uma determinada solicitação HTTP.
ctx.route
A rota correspondente para a solicitação HTTP atual. A propriedade route
é um objeto do tipo StoreRouteNode
ctx.params
Um objeto de parâmetros de rota
ctx.subdomains
Um objeto de subdomínios de rota. Existe apenas quando a rota faz parte de um subdomínio dinâmico
ctx.session
Referência a uma instância de Session criada para a solicitação HTTP atual.
ctx.auth
Referência a uma instância da classe Authenticator. Saiba mais sobre autenticação.
ctx.view
Referência a uma instância do renderizador Edge. Saiba mais sobre o Edge em Guia de visualização e modelos
ctx.ally
Referência a uma instância da classe Ally Manager para implementar login social em seus aplicativos. Saiba mais sobre Ally
ctx.bouncer
Referência a uma instância da classe Bouncer. Saiba mais sobre Autorização.
ctx.i18n
Referência a uma instância da classe I18n. Saiba mais sobre i18n
no guia Internacionalização.
Estendendo o contexto HTTP
Você pode adicionar propriedades personalizadas à classe de contexto HTTP usando macros ou getters. Certifique-se de ler o guia de extensão do AdonisJS primeiro se você for novo no conceito de macros.
import { HttpContext } from '@adonisjs/core/http'
HttpContext.macro('aMethod', function (this: HttpContext) {
return value
})
HttpContext.getter('aProperty', function (this: HttpContext) {
return value
})
Como as macros e getters são adicionados em tempo de execução, você deve informar o TypeScript sobre seus tipos usando o aumento do módulo.
import { HttpContext } from '@adonisjs/core/http'
declare module '@adonisjs/core/http' {
export interface HttpContext {
aMethod: () => ValueType
aProperty: ValueType
}
}
HttpContext.macro('aMethod', function (this: HttpContext) {
return value
})
HttpContext.getter('aProperty', function (this: HttpContext) {
return value
})
Criando contexto fictício durante os testes
Você pode usar o serviço testUtils
para criar um contexto HTTP fictício durante os testes.
A instância de contexto não é anexada a nenhuma rota; portanto, os valores ctx.route
e ctx.params
serão indefinidos. No entanto, você pode atribuir manualmente essas propriedades se necessário pelo código em teste.
import testUtils from '@adonisjs/core/services/test_utils'
const ctx = testUtils.createHttpContext()
Por padrão, o método createHttpContext
usa valores falsos para os objetos req
e res
. No entanto, você pode definir valores personalizados para essas propriedades, conforme mostrado no exemplo a seguir.
import { createServer } from 'node:http'
import testUtils from '@adonisjs/core/services/test_utils'
createServer((req, res) => {
const ctx = testUtils.createHttpContext({
req,
res
})
})
Usando a fábrica HttpContext
O serviço testUtils
está disponível apenas dentro de um aplicativo AdonisJS; Portanto, se você estiver criando um pacote e precisar acessar um contexto HTTP falso, poderá usar a classe HttpContextFactory.
import { HttpContextFactory } from '@adonisjs/core/factories/http'
const ctx = new HttpContextFactory().create()