Соглашение об именах для моделей, используемых для (де) сериализации запросов и ответов REST API - PullRequest
4 голосов
/ 07 мая 2020

Мне нужно создать в клиенте REST API некоторые классы для обработки (де) сериализации данных, и я не использую, как назвать классы осмысленным образом.

Например, с следующий API

GET  /User
POST /Message

Я думал об использовании этой структуры:

package com.example.model

import kotlinx.serialization.Serializable

object User {
    @Serializable
    data class Response(
        val username: String,
        val fullName: String
    )
}

object Message {
    @Serializable
    data class Request(
        val title: String,
        val message: String
    )
    @Serializable
    data class Response(
        val status: Int
    )
}

Но я не знаю, как обрабатывать что-то подобное (предположим, что все запросы и ответы имеют другую структуру):

GET    /User
POST   /Message
DELETE /Message

Я думал примерно так:

object UserGet { ... }
object MessagePost { ... }
object MessageDelete { ... }

Но тогда я не знаю, как с этим бороться:

GET    /User
GET    /User/{userId}
GET    /User/{userId}/AllMessages
POST   /Message
DELETE /Message

Есть ли соглашение для этого варианта использования? Как это обычно делается на стороне сервера?

1 Ответ

0 голосов
/ 23 мая 2020

Вы можете оставить свои имена классов, просто добавив к ним методы , которые соответствуют поддерживаемым методам запроса.

package com.example.model

import kotlinx.serialization.Serializable

object User {
    @Serializable
    data class Request( // either you or your routing library should parse incoming urls to deserialize this
        val user_id: String
    )
    @Serializable
    data class Response(
        val username: String,
        val fullName: String
    )
    fun get(req: Request): Response {
    } // GET /User/{user_id}
}

object Message {
    @Serializable
    data class Request(
        val title: String,
        val message: String
    )
    @Serializable
    data class Response(
        val status: Int
    )
    fun create(req: Request): Response {
    } // POST /Message
    fun delete(req: Request): Response {
    } // DELETE /Message
}

GET /user - вам необходимо определить поведение для этого. Я не вижу, что это будет делать в вашей системе на данный момент.

GET /user/{user_id}/AllMessages - это эффективно отображается на другой набор ресурсов. Новый класс может быть в порядке. Я бы также порекомендовал более каноническое имя, например GET /user/{user_id}/messages. Таким образом, вы можете предоставить параметры для разбивки на страницы, используя строку запроса ?limit=1000&offset=900

object UserMessages {
    @Serializable
    data class Request(
        val user_id: String,
        val limit: Int,
        val offset: Int
    )
    @Serializable
    data class Message(
        val message_id: String,
        val text: String
    )
    @Serializable
    data class Response(
        val messages: Array<Message>
    )
    fun get(req: Request): Response {
    } // GET /user/{user_id}/messages
}
...