【问题标题】:REST API hierarchy for endpoints with Spring RESTControllers带有 Spring RESTControllers 的端点的 REST API 层次结构
【发布时间】:2018-12-15 22:56:20
【问题描述】:

我有一些 REST API 的玩家资源的 URI:

http://localhost:8080/player

http://localhost:8080/player/3 ----> id=3 的播放器资源的 URI

我有这个游戏资源的 URI:

http://localhost:8080/player/3/games

http://localhost:8080/player/3/games/5 ---> id=5 的游戏资源的 URI,用于 id = 3 的玩家(玩此游戏的玩家)。

使用 Spring 框架,我想要两个 RestController,一个用于玩家资源,另一个用于游戏资源,但使用 @RequestMapping 注释我有这个:

@RestController
@RequestMapping("${spring.data.rest.base-path}" + "/players")
public class PlayerRestResource {

    @RequestMapping( method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public PlayerDto createPlayer(@RequestBody PlayerDTO newPlayerDTO) {
        ...
    }
....
}

但我不知道如何为这样的 gameRestResource 使用 RequestMapping 注释并获取玩家的 id:

@RestController
@RequestMapping("${spring.data.rest.base-path}" + "/player/idplayer/games")
public class GameRestResource {

    @RequestMapping( method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public GameDto createGame(@RequestBody GameDTO newGameDTO) {
        ...
    }
....
}

【问题讨论】:

    标签: java rest spring-boot web


    【解决方案1】:

    你必须在方法上添加你的特定映射,而不是类。

    为了保持一致性,您应该在路径中坚持使用单数或复数名词。例如。玩家对玩家或游戏对游戏。对于我的休息服务,我更喜欢单数名词——但这主要是一种主观意见。请记住,您的路径应该只包含名词而不是动词(诸如创建、检索、更新等操作)。 GET、POST、PUT、DETELE 等 HTTP 方法是您的操作,因此您的路径中不需要动词。

    您可以通过不同的方法返回资源。我建议你阅读这个question

    @RestController
    @RequestMapping("${spring.data.rest.base-path}" + "/player")
    public class PlayerRestResource {
    
        //This method can be accessed from /player/3
        //Id need to be placed in curly. 3 from url will be passed to the method
        @RequestMapping(path = "/{playerId}", method = RequestMethod.POST)
        //Use @PathVariable to bind the value from to url to the method parameter.
        public ResponseEntity<Player> getPlayer(@PathVariable("playerId") int playerId) {
        }
    
        //This is just like the above method.
        //This method can be accessed from /player/3/game/5
        @RequestMapping(path = "/{playerId}/game/{gameId}" method = RequestMethod.POST)
        public ResponseEntity<List<Game>> getGame(@PathVariable("playerId) int playerId, @PathVariable("gameId) int gameId) {
        }
    
    }
    

    格式化休息服务的快速速成课程。

    您总是希望在您的道路之上进行构建。基础变量应该是您的基础实体。

    创建新播放器 - 负载可以在正文中格式化为 JSON

    POST: example.com/player

    检索 ID 为 3 的玩家的信息。

    GET: example.com/player/3

    更新 ID 为 3 的玩家的信息 - Payload 可以在正文中格式化为 JSON

    PUT: example.com/player/3

    删除 ID 为 3 的玩家

    DELETE: example.com/player/3

    检索与 ID 为 3 的玩家相关联的 ID 为 5 的游戏信息。请注意,此路径应用于为特定用户更新特定玩家的数据

    GET: example.com/player/3/game/5

    创建新游戏 - Payload 可以在正文中格式化为 JSON

    POST: example.com/game

    检索 ID 为 5 的游戏信息 - 此数据不与任何玩家关联。这只是关于 ID 为 5 的特定游戏的数据

    GET: example.com/player/5

    所有以 /player 开头的路径都应该放在 PlayerController 类中,所有以 /game 开头的路径都应该放在 GameController 类中。

    我建议您阅读以下资源:

    https://martinfowler.com/articles/richardsonMaturityModel.html

    https://www.restapitutorial.com/

    https://spring.io/guides/tutorials/bookmarks/

    【讨论】:

    • 那我有一个大班,如果游戏包含更多资源怎么办?是否应该在 PlayerRestResource 类中编码?
    • 您发布的其余方法都将播放器作为其基本元素。所以你想对一个玩家执行一个动作。我会更新我的答案你给你一个例子。
    • @MABC 我已经更新了我的答案,并简要说明了如何分离您的资源。我建议您访问我提到的三个网站,它们应该可以帮助您入门。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2017-12-27
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多