【问题标题】:How to design API in Spring MVC?如何在 Spring MVC 中设计 API?
【发布时间】:2021-12-14 18:53:39
【问题描述】:

我有一个 Spring MVC 控制器,但我不确定它的设计是好是坏。据我所知,缺少 api 版本控制,但除此之外,我为文档实现了 Swagger 并添加了 SpringSecurity 并尝试遵循 YARAS(Yet Another RESTful API Standard) 来构建它,但我需要另一个眼睛来评论它。

@Slf4j
@Controller
@RequestMapping
@RequiredArgsConstructor
public class XGameController implements GameController {

    private final GameService gameService;

    private final ObjectMapper mapper;

    @RequestMapping(value = "/", method= RequestMethod.GET)
    public String index() {
        return "game";
    }

    @RequestMapping(value = "/login", method= RequestMethod.GET)
    public String login() {
        return "login";
    }

    @Secured("ROLE_USER")
    @RequestMapping(value = "/games", method= RequestMethod.POST)
    public String initializeGame(Model model) {
        log.info("New XGame is initializing...");
        Game game = new Game();
        game = gameService.initializeGame(game.getId());

        try {
            model.addAttribute("game", mapper.writeValueAsString(game));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
        }
        log.info("New XGame is initialized successfully!");
        return "game";
    }

    @Secured("ROLE_USER")
    @RequestMapping(value = "/games/{gameId}", method= RequestMethod.PUT)
    public @ResponseBody Game play(@PathVariable("gameId") String gameId,
                                   @RequestParam Integer pitNumber,
                                   @RequestParam String action) {
        log.info("Sowing stone is triggered...");
        return gameService.executeGameRules(UUID.fromString(gameId), pitNumber);
    }

    @RequestMapping(value = "/403", method= RequestMethod.GET)
    public String error403() {
        return "/error/403";
    }

}

我的大摇大摆的快照;

【问题讨论】:

标签: java spring spring-boot api spring-mvc


【解决方案1】:

一些建议:

  1. 使用代表您的controller 的上下文或想法的路径,您可以添加version

    @RequestMapping("/V1/xgame")

  2. 使用专门的注解,例如:@GetMapping@PostMapping 等...

  3. 对于/403,请使用具有含义的全名,例如/errors

  4. 使用您将返回给用户的自定义消息。为此,您需要ControllerAdvice

  5. Google 关于patterns and best practicesRest API 设计

  6. 阅读一些books 以获得更好的理解。

【讨论】:

  • 这样的设计对用户来说是不是太糟糕了,无法阅读一些书籍?我的意思是,看书根本不是一件坏事,但在这种设计方法的情况下,他需要它来提高自己吗?
  • 阅读书籍是每个学习过程的基础。看书和好书是显而易见的。
【解决方案2】:
  1. 首先,代替 @RequestMapping 使用特定的映射(Get、Post 等),并且映射类型的使用取决于您,您会发现使用它的原因更具体

  2. 如果您要从页面重定向到主页,请尝试使用 return "redirect:"/url"" 而不是直接返回 HTML 文件。

  3. 重命名你的错误方法,RequestMapping 值到一些更合理的名字。

  4. 而不是使用 return "/error/403" 使用 return "redirect:/error/403"

【讨论】:

    【解决方案3】:

    我会做出一些改变。

    1. /games/{gameId} 中,我会使用PATCH 而不是PUT。原因是PUT 旨在完全替换资源(在您的情况下为Game)。这似乎不是您在此端点中所做的。 PATCH 旨在部分更新资源,这似乎更适合您在这里所做的事情。

    2. 仍然在/games/{gameId} 中,我会使用请求正文来提供所需的数据而不是查询参数。它似乎不正确。查询参数比POSTPUTPATCH 更适合GET 请求。

    3. 我会将/403 重命名为其他名称,这实际上给出了关于403 是什么的一些背景信息。话虽如此,我会选择/error-pages/403。此外,我还会考虑从 swagger 规范中删除此端点。

    除此之外,我觉得还不错。

    【讨论】:

    • 为什么会有/403? 403 是 状态,而不是 URL。
    • 这也是我的第一个想法,但它似乎是获取 403 错误页面的方法。但是,这至少是值得商榷的。
    • 使用@RequestBody 并将整个模型作为参数会更好吗?它不会使模型更容易受到攻击吗?
    猜你喜欢
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2011-07-13
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2013-09-03
    相关资源
    最近更新 更多