2

I have this URI for players resource for some REST API:

http://localhost:8080/player

http://localhost:8080/player/3 ----> URI of a player resource with id=3

I have this URI for games resource:

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

http://localhost:8080/player/3/games/5 ---> URI of a game resource with id=5 for a player with id = 3 (the player playing this game).

With Spring framework i want two RestControllers, one for player resource and the other for game resource, but using @RequestMapping anotation i have this:

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

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

But I dont know how to use the RequestMapping anotation for a gameRestResource like this and get the id of the player:

@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) {
        ...
    }
....
}
MABC
  • 576
  • 2
  • 11
  • 29

1 Answers1

1

You have to add your specific mapping on the method, not class.

For consistency you should either stick to singular or plural noun in your path. E.g. Player vs Players or Game vs Games. I prefer singular noun for my rest services - but this is mostly a subjective opinion. Just remember your path should only contain nouns and never verbs(Actions such as create, retrieve, update...). HTTP Methods such as GET, POST, PUT, DETELE are your actions, there is therefore no need for verbs in your path..

You can return the resource by different approaches. I recommend you reading this 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) {
    }

}

A quick crash-course in formatting rest services.

You always want to build on top of your path. The base variable should be your base entity.

Create new player - Payload could be formatted as JSON in body

POST: example.com/player

Retrieve information about player with ID 3.

GET: example.com/player/3

Update information about player with ID 3 - Payload could be formatted as JSON in body

PUT: example.com/player/3

Delete player with ID 3

DELETE: example.com/player/3

Retrieve information about game with ID 5 that is associated with player with ID 3. Please note, that this is path should be used to update data on a specific player for a specific user

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

Create new game - Payload could be formatted as JSON in body

POST: example.com/game

Retrieve information about game with ID 5 - This data is not associated with any players. This is only data about the specific game with ID 5

GET: example.com/player/5

All your paths starting with /player should go into a PlayerController class, and all the paths starting with /game should be in GameController class.

I would suggest you to read the following resources:

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

https://www.restapitutorial.com/

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

kkflf
  • 2,435
  • 3
  • 26
  • 42
  • Then i will have a large class, what If game contains more resources? Should it be codified in PlayerRestResource class? – MABC Jul 07 '18 at 19:18
  • The rest methods that you posted are all referring to a player as its base element. So you want to perform an action on a player. I will update my answer you give you an example. – kkflf Jul 07 '18 at 19:43
  • @MABC I have updated my answer with a short explanation on how to seperate your resources. I suggest you to visit the three sites that I mentioned, they should help you get started. – kkflf Jul 07 '18 at 20:06