Как сделать данные, привязанные к запросу, глобально доступными в Ktor?

Строю микросервис в Кторе. Пока мы работаем в модуле приложения, Ktor предоставляет доступ к объекту call, который содержит данные авторизации.

Моя проблема в том, что мне нужно получить доступ к объекту call из класса уровня обслуживания. В Spring вы могли бы сделать это, обратившись к SecurityContext, который глобально доступен через ThreadLocal. Ktor, управляемый сопрограммами, не имеет такой возможности.

Действительно ли мне нужно передавать объект call через мои методы уровня обслуживания, или в Ktor есть способ иметь какой-то объект «контекста вызова», к которому вы можете получить доступ откуда угодно?


person Alan47    schedule 27.03.2019    source источник
comment
Возможно, стоит упомянуть, что у сопрограмм действительно есть CoroutineContext, который представляет собой просто карту.   -  person Moira    schedule 27.03.2019
comment
Проблема с CoroutineContext в том, что его легко потерять по пути (например, при вызове async). Во всех этих местах контекст сопрограммы должен передаваться явно, о чем легко забыть (компилятор не будет жаловаться). Но я согласен с некоторой дисциплиной, это решение.   -  person Alan47    schedule 23.05.2019
comment
Для тех, кто увидит это в будущем, я задал / ответил на вопрос о том, как реализовать контекст сопрограммы здесь: stackoverflow.com/questions/63674112/   -  person MyrionSC2    schedule 01.09.2020


Ответы (1)


Я думаю, что на данный момент нет встроенной официальной возможности.

Я написал функцию Ktor, которая реализует это поведение. Ответ сложно описать несколькими словами.

Посмотрите код + образцы, если вам интересно. Также предоставляется руководство по установке.

= ›https://github.com/MaaxGr/ktor-globalcalldata


Вот небольшой фрагмент того, как выглядит моя dsl:

Вызов функции приостановки test () прямо или косвенно из маршрута:

routing {
    get("/test") {
        test()
        call.respond("OK")
    }
}

Доступ к объекту вызова через callData().call

suspend fun test() {
    val url = callData().call.request.uri
    println(url) // prints "/test"
}

Библиотека также позволяет добавлять настраиваемые свойства, которые можно привязать к текущей сопрограмме / вызову.

person Caelis    schedule 17.12.2020