Перенаправления в Слугу
Как правильно обработчик Servant ответить перенаправлением? Я работаю в навигационном REST-приложении и хотел бы отвечать на POST-запросы, которые создают ресурсы с перенаправлением на соответствующие пути списка ресурсов GET. Так, например, POST /foos должен перенаправить на GET /foos после создания foo. Я не мог найти четкий способ сделать это в документации.
1 ответ
Существует один простой (но немного хакерский) ответ, и руководство для того, чтобы сделать первый вариант устаревшим (РЕДАКТИРОВАТЬ: и третий, лучший вариант, на самом деле).
Текущее типичное решение для этого состоит в том, чтобы просто использовать тот факт, что Handler
монада имеет MonadError ServantErr
экземпляр, и это ServantErr
это очень общий "тип ответа", который действительно может описывать HTTP-ответ для ошибки приложения, но также может быть перенаправлением или многими другими вещами. Таким образом, вы можете сделать что-то вроде throwError $ err301 { errHeaders = [("Location", "https://haskell.org/")] }
, Это некрасиво, потому что мы похитили бит "ошибки" для некоторого успешного рабочего процесса. Но это работает, и это одна строка кода.
Я исследовал альтернативные подходы, которые позволяют вам смешивать безопасные по типу ссылки с перенаправлениями, чтобы легко перенаправлять на другие конечные точки / страницы вашего приложения. Сейчас это уже устарело, но, вероятно, его можно заставить работать без особых проблем.
И, увидев этот вопрос, я только сейчас подумал о третьем варианте. Потребовалось немного времени, чтобы поэкспериментировать с ним и похоже, что он работает! Вы можете увидеть код с примером использования этого в этой сути. Дайте мне знать, если у вас есть какие-либо вопросы. Возможно, мы захотим добавить это к слуге. Не стесняйтесь поднять это на трекере, если вы думаете, что это достаточно хорошо. Суть этого подхода заключается в определении обычая PostRedirect
он имеет правильную форму (без тела ответа, заголовок Location с типом по вашему выбору и параметризован кодом состояния, который вы хотите использовать при перенаправлении) и небольшую функцию, которая соответствующим образом переносит местоположение перед возвратом.