Beagle v1.7 não é mais mantida ativamente. A versão documentada que você está visualizando pode conter funcionalidades depreciadas. Para obter as funcionalidades mais recentes, consulte a nossa última versão .
Esta seção explica como criar um backend sem fazer uso das configurações prontas para os frameworks Spring
ou Micronaut
. Você encontrará as ferramentas necessárias para criar um Backend(BFF) para o seu projeto.
É importante reforçar que:
Starters
da configuração inicial já fazem todo o processo descrito nesta página e adicionam automaticamente as configurações abaixo.Para configurar seu BFF manualmente, siga os seguintes passos:
<dependency>
<groupId>br.com.zup.beagle</groupId>
<artifactId>framework</artifactId>
<version>${beagle_version}</version>
</dependency>
ObjectMapper
do JacksonNa configuração do projeto no backend é necessário realizar o setup doObjectMapper
do Jackson para o Beagle. Existem duas maneiras de fazer isso:
Primeiro, você pode registrar o BeagleModule
no seuObjectMapper
.
val mapper = // however your ObjectMapper is initialized
mapper.registerModule(BeagleModule)
Ou você pode utilizar a função utilitáriabeagleObjectMapper
. Essa função retorna um ObjectMapper
usando o jacksonObjectMapper()
com um BeagleModule
registrado.
val mapper = BeagleSerializationUtil.beagleObjectMapper()
BeagleCacheHandler
Para fazer uso do mecanismo de cache, o Beagle oferece uma classe chamada BeagleCacheHandler
e uma interface chamada RestCacheHandler
. É recomendado usá-las como um filtro de resposta em seu projeto.
A classe BeagleCacheHandler
contém um template de implementação do protocolo. Este template é independente da estrutura HTTP e REST e utiliza o método de instância handleCache.
No entanto, ele precisa interagir com os detalhes da resposta HTTP, e é aqui que o RestCacheHandler
é acionado.
javax.servlet
Para demonstrar o funcionamento dessas classes, o exemplo abaixo foi implementado utilizando uma classe do javax.servlet
.
javax.servlet.Filter
que aplica o protocolo de cache para toda resposta dada pelo backend do qual ele faz parte.javax.servlet.HttpServletResponse
requer, foi omitida. Essa omissão é apontada nos códigos com comentários.RestCacheHandler
Você precisa implementar a interface RestCacheHandler
, composta por quatro transformações que o manipulador precisa executar no seu objeto de resposta. É genérico e deve ser especializado para o tipo de resposta disponibilizada em sua estrutura HTTP. Seus métodos devem se comportar conforme descrito abaixo:
Método | Comportamento |
---|---|
addHashHeader(response, header) | Retorna a resposta com header adicionado aos headers dela na chave BeagleCacheHandler.CACHE_HEADER |
addStatus(response, status) | Retorna uma resposta com status ao invés de uma resposta com o status do HTTP atual |
callController(response) | Retorna a resposta resultante da chamada do controlador atual (geralmente prosseguindo na cadeia de filtros). |
getBody(response) | Retorna o corpo da resposta como uma String |
class MyCacheHandler(
private val request: HttpServletRequest,
private val chain: FilterChain
) : RestCacheHandler<HttpServletResponse> {
override fun addHashHeader(
response: HttpServletResponse,
header: String
): HttpServletResponse {
response.setHeader(BeagleCacheHandler.CACHE_HEADER, header)
return response
}
override fun addStatus(
response: HttpServletResponse,
status: Int
): HttpServletResponse {
response.status = status
return response
}
override fun callController(response: HttpServletResponse): HttpServletResponse {
this.chain.doFilter(this.request, response)
return response
}
// There is no direct way to access an HttpServletResponse's content,
// this is only to demonstrate the idea
override fun getBody(response: HttpServletResponse) = response.content
}
Filter
que utilize oBeagleCacheHandler
Logo depois, você precisa criar uma instância do BeagleCacheHandler
e chamar o método handleCache
nele. O construtor do BeagleCacheHandler
pode aceitar uma lista de strings que representam a regex do endpoint para não ser armazenada em cache.
Eles devem ser um java.util.regex.Pattern
válido. Os parâmetros para o método handleCache
estão descritos abaixo.
Esse filtro retorna uma resposta totalmente transformada:
Parâmetro | Descrição |
---|---|
endpoint | O endpoint requisitado. |
receivedHash | O valor doBeagleCacheHandler.CACHE_HEADER que veio com a requisição. |
initialResponse | Uma instância do tipo de resposta a ser transformada. |
restCacheHandler | Instância da sua implementação do RestCacheHandler . |
class MyFilter : Filter {
private val beagleCacheHandler = BeagleCacheHandler()
override fun doFilter(
request: ServletRequest?,
response: ServletResponse?,
chain: FilterChain?
) {
if (request is HttpServletRequest
&& response is HttpServletResponse
&& chain != null) {
this.beagleCacheHandler.handleCache(
request.requestURI,
request.getHeader(BeagleCacheHandler.CACHE_HEADER),
response,
MyCacheHandler(request, chain)
)
}
}
}
Para que o Beagle tenha o funcionamento esperado na filtragem de elementos por plataforma, é necessário realizar algumas configurações.
É recomendado registrar um filtro ou um interceptor que verifique a resposta de seu BFF e filtre os elementos enviados de acordo com a plataforma especificada no header customizado beagle-platform
.
A classe BeaglePlatformUtil
foi criada disponibilizando algumas ferramentas para facilitar essa configuração e ser usada em seu filtro/interceptor. Elas são especificadas abaixo:
Constante | Descrição |
---|---|
BEAGLE_PLATFORM_HEADER | Nome do campo header utilizado pelo Beagle para verificar com qual plataforma o BFF está interagindo |
Método | Descrição |
---|---|
treatBeaglePlatform(currentPlatform, jsonNode) | Retorna o JsonNode passado como parâmetro jsonNode com os elementos cuja plataforma não correspondem ao parâmetro currentPlatform removidos |
Um exemplo de interceptor para Spring:
class BeaglePlatformInterceptor(private val objectMapper: ObjectMapper) : HandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
request.setAttribute(
BeaglePlatformUtil.BEAGLE_PLATFORM_HEADER,
request.getHeader(BeaglePlatformUtil.BEAGLE_PLATFORM_HEADER)
)
return true
}
override fun postHandle(
request: HttpServletRequest,
response: HttpServletResponse,
handler: Any,
modelAndView: ModelAndView?
) {
val responseWrapper = (response as ContentCachingResponseWrapper)
val jsonTree = this.objectMapper.readTree(responseWrapper.contentAsByteArray)
BeaglePlatformUtil.treatBeaglePlatform(
request.getHeader(BeaglePlatformUtil.BEAGLE_PLATFORM_HEADER),
jsonTree
)
val jsonData = jsonTree.toPrettyString()
responseWrapper.resetBuffer()
responseWrapper.outputStream.write(jsonData.toByteArray())
responseWrapper.setContentLength(jsonData.length)
}
}
No exemplo acima, preHandle
passa a informação da plataforma pela qual a requisição foi feita como um atributo da request, para que ele possa ser acessado posteriormente pelo BFF e facilite a identificação da plataforma. Já o postHandle
realiza o trabalho de filtrar os elementos devidos de acordo com a plataforma alvo na resposta de seu BFF.
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.