web-dev-qa-db-ja.com

春のサブリソースREST

メッセンジャーアプリを作成しようとしています。

MessageResourceからCommentResourceを呼び出す必要があります。

MessageResourcesとCommentResourcesを分離したいのですが。

私はこのようなことをしています:

MessageResource.Java

@RestController
@RequestMapping("/messages")
public class MessageResource {

    MessageService messageService = new MessageService();

    @RequestMapping(value = "/{messageId}/comments")
    public CommentResource getCommentResource() {
        return new CommentResource();
    }
}

CommentResource.Java

@RestController
@RequestMapping("/")
public class CommentResource {

    private CommentService commentService = new CommentService();

    @RequestMapping(method = RequestMethod.GET, value="/abc")
    public String test2() {
        return "this is test comment";
    }
}

が欲しいです

http:// localhost:8080/messages/1/comments/abc

これは「テストコメントです」を返します。

何か案が??

PS:簡単なWordで、JAX-RS sub-resourceでの同等の実装spring-restについて知りたい

15
prranay

あなたのURL( http:// localhost:8080/messages/1/comments/abc )は、コメントがメッセージにネストされていることを示唆しています。コントローラは次のようになります。

@RestController
@RequestMapping("/messages")
public class MessageResource {

    @RequestMapping(value = "/{messageId}")
    public String getCommentResource(@PathVariable("messageId") String messageId) {
        //test
        return messageId;
    }

    @RequestMapping(value = "/{messageId}/comments/{commentsContent}")
    public String getCommentResource(
                      @PathVariable("messageId") String messageId, 
                      @PathVariable("commentsContent") String commentsContent) {
        //test
        return messageId + "/" + commentsContent;
    }
}

MessageResourceクラスで何をしたいかは完全にはわかりませんが、アイデアはそこにあります。

残り-HTTPメソッド

現時点では、これらの使用はGetリクエストです。ただし、適切なHttpメソッドの使用を検討する必要があります。

  • 取得:リソースを読み取る
  • 投稿:リソースを作成する
  • 置く:更新
  • 削除:削除:)

これを見てください: http://www.restapitutorial.com/lessons/httpmethods.html

投稿の例:

@RequestMapping(method=RequestMethod.POST, value = "/{messageId}/comments/{commentsContent}")
    public ResponseEntity<String> getCommentResource(
                                  @PathVariable("messageId") String messageId, 
                                  @RequestBody Comment comment) {
        //fetch the message associated with messageId
        //add the comment to the message
        //return success
        return new ResponseEntity<String>(HttpStatus.OK);
 }

クラス名

また、これらのクラスの名前をMessageControllerとCommentControllerに個人的に変更します。

コメントの後に編集-コントローラーを分割

文字通りコントローラーを分割することができます(以前のものに近い):

@RestController
@RequestMapping("/messages")
public class MessageResource {

    @RequestMapping(value = "/{messageId}")
    public String getCommentResource(@PathVariable("messageId") String messageId) {
        //test
        return messageId;
    }
}

@RestController
@RequestMapping("/messages")
public class CommentResource {

    @RequestMapping(value = "/{messageId}/comments/{commentsContent}")
    public String getCommentResource(
                      @PathVariable("messageId") String messageId, 
                      @PathVariable("commentsContent") String commentsContent) {
        //test
        return messageId + "/" + commentsContent;
    }
}
7
alexbt

あなたが探しているものは Jersey などのJAX-RS実装でサポートされており、Sub-Resourcesと呼ばれます。自然にネストされる大きなAPIを構築する場合、サブリソースは非常に便利な機能です。

Spring BootのデフォルトのREST実装はJAX-RSではなくSpringMVCです。 JerseyをSpring Bootで使用することは可能ですが、それを設定しようとするのは少し複雑であり、コミュニティで十分に使用/サポートされているようには見えません。

余談ですが、 DropWizard は素晴らしいです!

4
Paul Murphy

また、強制的にJAX-RSからSpring-MVCに移行しています。

JAX-RSの場合と同じように、これを行うためのエレガントな方法をまだ探しています。

私が試したことを共有しています。

_@RestController
@RequestMapping("parents")
public class ParentsController {

    @RequestMapping(method = RequestMethod.GET,
                    produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<List<Parent>> read() {
    }

    @RequestMapping(method = RequestMethod.GET,
                    path = "/{id:\\d+}",
                    produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<Parent> read(@PathVariable("id") final long id) {
    }
}
_

そして、ChildrenController

_@RestController
@RequestMapping("/parents/{parentId:\\d+}/children")
public class ChildrenController {

    @RequestMapping(method = RequestMethod.GET,
                    produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseBody
    public List<Child> read(@PathVariable("parentId") final long parentId) {
    }

    @RequestMapping(method = RequestMethod.GET, path = "/{id:\\d+}",
                    produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseBody
    public Child read(@PathVariable("parentId") final long parentId,
                     @PathVariable("id") final long id) {
    }
}
_

私が見つけた2つの問題、

_@PathVariable_はフィールドには適用されません。

できません@PathVariable("parentId") private long parentId;

ChildrenControllerの複数マッピングの自由意志はありません

JAX-RSの優れている点は、ChildrenControllerにクラスレベルの_@Path_が含まれている場合でも、ChildrenControllerを異なるパスにマップできることです。

_@Path("/children");
public class ChildrenResource {
}

@Path("/parents")
public class ParentsResource {

    @Path("/{id}/children")
    public ChildrenResource resourceChildren() {
    }
}


/children
/parents/{id}/children
_
2
Jin Kwon

Springブートでは、@ Autowired Springコンセプトを使用してJAX-RSサブリソースコンセプトを実装できます。子リソースクラスのオブジェクトを作成すると、Springは実行時に初期化し、そのオブジェクトを返します。手動でオブジェクトを作成しないでください。のような:上記のシナリオ

 - MessageResource.Java

@RestController
@RequestMapping("/messages")
public class MessageResource {

    MessageService messageService = new MessageService();
    @Autowired
    @Qualifier("comment")
    CommentResource comment;

    @RequestMapping(value = "/{messageId}/comments")
    public CommentResource getCommentResource() {
        return comment;
    }
}    

 - CommentResource.Java

@RestController("comment")
@RequestMapping("/")
public class CommentResource {

    private CommentService commentService = new CommentService();

    @RequestMapping(method = RequestMethod.GET, value="/abc")
    public String test2() {
        return "this is test comment";
    }
}



Now it will work like sub-resource
http://localhost:8080/messages/1/comments/abc

You can send any type of request.
1
Tapan

2つのクラスを作成し、constantを使用して、子リソースを親リソースで参照するだけです。これは、2つのクラス間のリンクを作成し、開発者にそれらの間の関係を理解させるのに役立ちます。

そう:

@RequestMapping(value= MessageController.URL)
public class MessageController {
    public static final String URL= "/messages";
}

そして:

@RequestMapping(value = MessageController.URL + "/{idMessage}/comments")
public class CommentController {

}

また、コントローラーをさまざまなパッケージに分割して、パッケージ組織でこの階層を表示することもできます。

com.company.web.message.MessageController
com.company.web.message.comment.CommentController 
0
Dherik

MessagesController.Java

@RestController
@RequestMapping(value = "/messages")
public class MessageController {

    @Autowired
    private MessagesService messageService;

}

CommentController.Java

@RestController
@RequestMapping("/messages/{messageId}/comments")
public class CommentController {


    @GetMapping
    public List<Comment> getComments(@PathVariable("messageId") Long messageId) {
        System.out.println("Get "+messageId);

        return null;
    }

}
0
PraKhar