This article will take about 2 minutes to read.
We should divide network requests into a series of different classes/interfaces
Service
EndpointXYZ
interfacesRequest
/ Response
class per endpointThe Service
only exists for us to scope network requests correctly for our features
By cleanly separtating network modesl from domain models, we are partitioning the code into a section that we own, and a section that the server owns. Explicitly including a translation between the two solidifies and clarifies the contract that the two are agreeing to share. This also helps to mitigate the issues associated with sharing models across features.
interface ServiceAuthentication :
EndpointAuthSignIn
EndpointAuthRegister
EndpointAuthRefresh
Notice that a service is comprised of several endpoints. An endpoint can belong to multiple services.
interface EndpointAuthSignIn {
@POST("/auth/signin")
suspend fun signIn(@Body request: Request): retrofit2.Response<Response>
data class Request(
@SerializedName("username") val username: String,
@SerializedName("password") val password: String,
)
data Response(
@SerializedName("token") val token: String,
@SerializedName("user") val user: User,
) {
data class User(
@SerializedName("firstName") val name: String,
@SerializedName("lastName") val name: String,
)
}
}
A Service is a collection of endpoints. It DOES NOT correlate directly with the microservice implementation on the server.
Each Endpoint defines its own Request and Response
Requests and Responses should be automatically generated from actual server responses.
It’s the responsibility of the Respository class (or repository UseCase) to convert Request and Response types to domain types.