O que muda é a forma com que você está passando os dados.
Na chamada com FromQuery você irá passar os parâmetros via QueryString, assim:
http://seu-site.com/filmes?skip=1&take=3
Na chamada sem o FromQuery você está fazendo o binding via parâmetro de rota. É a mesma coisa de escrever dessa forma:
[HttpGet("{skip}/{take}")]
public IEnumerable<Filme> RecuperaFilmes([FromRoute] int skip, [FromRoute] int take)
{
return filmes.Skip(skip).Take(take);
}
Com isso, passará seus dados assim:
http://seu-site.com/filmes/1/3
Eu recomendo sempre usar os atributos (FromQuery, FromRoute, FromBody...) para facilitar o binding, e talvez ainda mais importante, ajudar na documentação do endpoint.
Agora, sobre quando usar um ou outro, vai depender. Se você quer criar algum endpoint que faça uso do conceito de acessos a recursos (como feito no REST) e/ou explicitar uma relação hierárquica, rotas pode ser uma boa. Caso você queira apenas passar parâmetros de filtros, poderia usar uma QueryString.
Segue um exemplo de como você poderia usar cada um:
GET http://seu-site.com/filmes/1
Aqui você está acessando a coleção de recursos "filmes" e buscando o filme com id = 1.
GET http://seu-site.com/filmes?ano_lancamento=2020&genero=acao
Aqui você está acessando a coleção de recursos "filmes" e buscando todos com ano de lançamento = 2020 e gênero = ação.
Olha esse exemplo (da API do GIT)
POST /repos/{owner}/{repo}/git/commits
Repare que existe uma certa estrutura relacional/hierárquica bem definida, até no fim, chegar na coleção de commits.