- Vamos começar criando um método em courseService.ts para buscar pelo curso no banco de dados:
- Obs.: Repare que estamos utilizando o operador ILIKE para pesquisar uma string em qualquer parte do nome do curso e sem diferenciar maiúsculas e minúsculas. O sequelize permite fazer isso de forma bem simples.
// src/services/course-service.ts
// ...
},
findByName: async (name: string) => {
const courses = await Course.findAll({
attributes: ['id', 'name', 'synopsis', ['thumbnail_url', 'thumbnailUrl']],
where: {
name: {
[Op.iLike]: `%${name}%`
}
}
})
return courses
}
}
export { courseService }
- Agora precisamos criar o método search no controlador para chamar o método findByName:
- Obs.: Repare que estamos usando pela primeira vez o req.body para ler dados do corpo da requisição, que nesse caso será o nome do curso a ser pesquisado.
// src/controllers/courses-controller.ts
},
// GET /courses/search?name=
search: async (req: Request, res: Response) => {
const { name } = req.query
try {
if (typeof name !== 'string') throw new Error('name param must be of type string');
const courses = await courseService.findByName(name)
return res.json(courses)
} catch (err) {
if (err instanceof Error) {
return res.status(400).json({ message: err.message })
}
}
}
}
export { coursesController }
- Crie uma rota para a pesquisa e inclua o método do controlador:
- Obs.: Mais uma vez, é fundamental que a rota de pesquisa fique acima da rota que contém o parâmetro :id para que o termo “search” não se confunda com um parâmetro.
// src/routes.ts
// ...
router.get('/courses/featured', coursesController.featured)
router.get('/courses/newest', coursesController.newest)
router.get('/courses/search', coursesController.search)
router.get('/courses/:id', coursesController.show)
export { router }
- Agora já podemos testar pesquisando pelo nome de algum curso e ver que funciona.
- Vamos ainda adicionar paginação aos nossos resultados. Para isso vamos utilizar a função getPaginationParams que criamos anteriormente no controlador obtendo assim os parâmetros da query e então passaremos eles para o método de busca:
// src/controllers/courses-controller.ts
},
// GET /courses/search
search: async (req: Request, res: Response) => {
const { name } = req.query
const [page, perPage] = getPaginationParams(req.query)
try {
if (typeof name !== 'string') throw new Error('name param must be of type string');
const courses = await courseService.findByName(name, page, perPage)
return res.json(courses)
} catch (err) {
if (err instanceof Error) {
return res.status(400).json({ message: err.message })
}
}
}
}
export { coursesController }
- Inclua as alterações necessárias no serviço para receber os novos parâmetros e obter os resultados do banco de dados em partes obtendo também a contagem total através do método findAndCountAll:
// src/services/course-service.ts
},
findByName: async (name: string, page: number, perPage: number) => {
const offset = (page - 1) * perPage
const { count, rows } = await Course.findAndCountAll({
attributes: ['id', 'name', 'synopsis', ['thumbnail_url', 'thumbnailUrl']],
where: {
name: {
[Op.iLike]: `%${name}%`
}
},
limit: perPage,
offset
})
return {
courses: rows,
page,
perPage,
total: count
}
}
}
export { courseService }
- Teste novamente e veja que agora já temos a paginação funcionando.