Как работать с Retrofit? Какие основные компоненты и аннотации?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Работа с Retrofit: основные компоненты и аннотации
Retrofit — это типобезопасный HTTP-клиент для Android и Java, разработанный Square. Он превращает ваш REST API в Java/Kotlin интерфейс, значительно упрощая сетевые запросы, их обработку и интеграцию.
Основные компоненты Retrofit
1. Retrofit экземпляр
Центральный объект, через который конфигурируется и создается клиент. Настраивается с помощью паттерна Builder:
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(OkHttpClient.Builder().build())
.build()
2. Интерфейс API
Определяет конечные точки и параметры запросов через аннотации:
interface UserApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): User
@POST("users")
suspend fun createUser(@Body user: User): Response<User>
}
3. Конвертеры
Преобразуют данные между сетевыми форматами (JSON, XML, Protocol Buffers) и объектами Java/Kotlin:
- GsonConverterFactory (наиболее популярный)
- MoshiConverterFactory
- JacksonConverterFactory
- ScalarsConverterFactory (для примитивных типов)
4. Адаптеры вызовов
Определяют, как будут выполняться запросы:
- DefaultCallAdapterFactory (для Call<T>)
- RxJava2CallAdapterFactory (для RxJava)
- CoroutineCallAdapterFactory (для Kotlin Coroutines)
5. Интерсепторы
Добавляются через OkHttpClient для модификации запросов/ответов:
- LoggingInterceptor - логирование
- AuthInterceptor - добавление заголовков авторизации
- CacheInterceptor - кэширование
Ключевые аннотации Retrofit
Аннотации методов HTTP
@GET("posts") // GET запрос
@POST("users") // POST запрос
@PUT("users/{id}") // PUT запрос
@DELETE("users/{id}") // DELETE запрос
@PATCH("users/{id}") // PATCH запрос
@HTTP(method = "CUSTOM", path = "custom")
Аннотации параметров пути и запроса
// Параметры пути (Path parameters)
@GET("users/{id}")
fun getUser(@Path("id") userId: String): Call<User>
// Параметры запроса (Query parameters)
@GET("search")
fun search(@Query("q") query: String): Call<SearchResult>
// Динамические query параметры
@GET("users")
fun getUsers(@QueryMap filters: Map<String, String>): Call<List<User>>
// Статичные query параметры
@GET("users?sort=desc")
fun getUsers(): Call<List<User>>
Аннотации тела запроса и форм
// Тело запроса (обычно JSON)
@POST("users")
fun createUser(@Body user: User): Call<User>
// Форма-кодированные данные
@FormUrlEncoded
@POST("login")
fun login(
@Field("username") username: String,
@Field("password") password: String
): Call<AuthResponse>
// Мультипарт запросы (для файлов)
@Multipart
@POST("upload")
fun uploadFile(
@Part("description") description: RequestBody,
@Part file: MultipartBody.Part
): Call<UploadResponse>
Аннотации заголовков
// Статичные заголовки
@Headers("Cache-Control: max-age=640000")
@GET("posts")
fun getPosts(): Call<List<Post>>
// Динамические заголовки
@GET("profile")
fun getProfile(@Header("Authorization") token: String): Call<Profile>
// Несколько заголовков
@GET("secured/data")
fun getSecuredData(@HeaderMap headers: Map<String, String>): Call<Data>
Типичный workflow работы с Retrofit
1. Добавление зависимостей
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'
}
2. Создание модели данных
data class User(
@SerializedName("id") val userId: Int,
@SerializedName("name") val userName: String,
@SerializedName("email") val email: String
)
3. Создание и использование сервиса
class UserRepository {
private val apiService: UserApiService
init {
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(
OkHttpClient.Builder()
.addInterceptor(LoggingInterceptor())
.build()
)
.build()
apiService = retrofit.create(UserApiService::class.java)
}
suspend fun fetchUser(userId: Int): Result<User> {
return try {
val response = apiService.getUser(userId)
if (response.isSuccessful) {
Result.success(response.body()!!)
} else {
Result.failure(Exception("HTTP error: ${response.code()}"))
}
} catch (e: Exception) {
Result.failure(e)
}
}
}
Лучшие практики
- Используйте синглтон для Retrofit экземпляра
- Обрабатывайте ошибки через try-catch и проверку response.isSuccessful()
- Добавляйте таймауты в OkHttpClient
- Используйте интерсепторы для логирования и добавления общих заголовков
- Тестируйте через MockWebServer
- Разделяйте ответственность - выносите сетевую логику в отдельный слой (Repository)
Retrofit значительно упрощает работу с сетевыми запросами, предоставляя чистый, типобезопасный API, который легко тестировать и поддерживать. Его модульная архитектура позволяет гибко настраивать преобразование данных, обработку ошибок и адаптацию к различным асинхронным механизмам.