AULA 28 MÓDULO 2 programação funcional ⏱ 50 min

Programação Funcional em APIs

Async/await como funcional assíncrono. map/filter para DTOs e acesso. Result type para erros explícitos. Funcional no dia a dia de uma API.

async/awaitDTOResult typemapfiltererrosAPI

Async/Await é funcional

As funções async/await do JavaScript são a forma funcional de lidar com operações assíncronas. Em vez de mutar estado com callbacks, você encadeia transformações de Promise.

por que importa para APIs
Todo endpoint Express lida com I/O assíncrono: banco, APIs externas, arquivos. Async/await com funções puras torna esse código linear, legível e testável.

Array methods em APIs REST

No dia a dia de uma API, você usa constantemente métodos funcionais para transformar dados antes de devolver ao cliente.

CASOS REAIS EM APIS
map → DTO
Transformar entidade do banco em DTO sem campos sensíveis (sem password, sem __v)
filter → acesso
Filtrar dados que o usuário tem permissão de ver
reduce → agregação
Calcular totais, contar por categoria, agrupar por data
sort → ordenação
Ordenar resultados antes de retornar
flatMap → expansão
Converter lista de objetos com sub-arrays em lista plana

Tratamento funcional de erros

O padrão funcional para erros em APIs usa try/catch com funções async, mas o padrão mais robusto é o Result type — retornar {data, error} em vez de lançar exceções.

🎯
regra de ouro
Nunca deixe um erro não tratado chegar ao cliente como 500 Internal Server Error. Capture, classifique e retorne erros semânticos: 400 (validação), 401 (auth), 403 (autorização), 404 (not found), 409 (conflito), 500 (bug).
javascript
// Programação funcional em handler de API
const toDTO  = user => ({ id: user.id, name: user.name, email: user.email })
const isActive = user => user.active && !user.deletedAt

app.get('/users', async (req, res) => {
  try {
    const rawUsers = await db.query('SELECT * FROM users')

    const users = rawUsers
      .filter(isActive)    // só ativos
      .map(toDTO)          // sem campos sensíveis
      .sort((a,b) => a.name.localeCompare(b.name))

    res.json({
      data: users,
      total: users.length
    })
  } catch (err) {
    console.error(err)
    res.status(500).json({ error: 'Erro interno' })
  }
})

// Padrão Result type (mais robusto)
const findUser = async (id) => {
  try {
    const user = await db.findById(id)
    if (!user) return { data: null, error: 'NOT_FOUND' }
    return { data: user, error: null }
  } catch {
    return { data: null, error: 'DB_ERROR' }
  }
}
quiz · aula 28
Teste seus conhecimentos
0/3 respondidas
QUESTÃO 01
Por que usar map() para transformar dados antes de retornar na API?
QUESTÃO 02
O que é o padrão Result type?
QUESTÃO 03
Qual status code retornar quando o recurso não existe?
0/3