-
Notifications
You must be signed in to change notification settings - Fork 30
Add JAX-RS PATCH annotation #36
Add JAX-RS PATCH annotation #36
Conversation
* | ||
* @author Eric Christensen | ||
*/ | ||
class PATCHSpec extends FunSpec with BeforeAndAfterAll with ShouldMatchers with MockitoSugar { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see a test with an actual stood up service. Might fit in https://github.com/cerner/beadledom/blob/c2125c7228f9a778b56a07615f00a4d729a86270/client/beadledom-client-test/src/test/scala/com/cerner/beadledom/client/ClientServiceSpec.scala
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PATCH used with an actual stood up service in the "retrieves the resources from different clients" test d582c3a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be a separate test directly in the describe("Proxied Clients")
block that tests only that patch works.
response.getStatus shouldBe 200 | ||
} | ||
|
||
it("should change the request model fields") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to have these two test, when you are calling the function with the same input twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are indeed the same function calls with the same parameters but it seemed appropriate to have two different "it" descriptors, one for just making sure that PATCH is called successfully and one to make sure that serialization takes place properly by making sure the server performed a change and returned it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would merge the two into one test. We are not testing two different aspects of the method here. Status code 200 means the request is served successfully. For PATCH a successful request mean that the resource is patched correctly. So, having these two checks in one test makes sense IMO.
response.getStatus shouldBe 200 | ||
|
||
val newModel: FakeModel = mapper.readValue(response.getContentAsString, classOf[FakeModel]) | ||
newModel.name shouldBe "newName" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory, if this was a real patch shouldn't these responses be what you sent to the patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PATCH resource updates the request that was sent to it. Normally the update would be to an existing resource in a database, but for the purposes of just performing an operation on the server this is fine.
@@ -28,6 +28,10 @@ | |||
@JsonProperty("inner_models") | |||
public List<FakeInnerModel> innerModels; | |||
|
|||
public FakeModel() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did you add a default constructor? the only place I see you using it is here where you use the constructor that already exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default constructer and the setters were added to make the creating of the FakeModel more like the builder pattern. It is used in the Spec at the recommendation of Brian.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We didn't break of the existing tests using this model did we? I can't imagine so but you never know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope all tests pass even after model change
model.setName("newName"); | ||
return Response.ok(model).build(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra newline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure exactly what we would say about it, but it seems like we would want to add the fact we added a Edit: In case you're not sure, the changes would be made under the docs module. We use reStructuredText as our markup. |
@b-boogaard what do you think of this? a1fac9f |
I think I would add it either above or below the @johnlcox @sparuvu @lal-s @nimeshsubramanian thoughts? |
How about something like: JAX-RS 2.0 (see section 3.3 for Resource Methods) does not require implementations to support the
As long as a service has
I think this could use a bit a clean up but I feel like it reads a bit better. Thoughts? |
|
||
val jsonNewTwo = JsonTwo.create("New Json", "Hola") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please differentiate jsonNewTwo
from jsonNewOne
(just change Hola to Hola1
and Hola2
or something simple)
@Target({ElementType.METHOD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@HttpMethod("PATCH") | ||
public @interface PATCH { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please add some javadoc to this.
response.getStatus shouldBe 200 | ||
} | ||
|
||
it("should change the request model fields") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would merge the two into one test. We are not testing two different aspects of the method here. Status code 200 means the request is served successfully. For PATCH a successful request mean that the resource is patched correctly. So, having these two checks in one test makes sense IMO.
docs/source/manual/jaxrs.rst
Outdated
PatchObject patchObject); | ||
|
||
.. _RFC: https://tools.ietf.org/html/rfc5789 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this?
PATCH
--------------
`PATCH <https://github.com/ktoso/maven-git-commit-id-plugin>`_ is a HTTP verb (similar to GET, POST, DELETE, PUT) to push partial changes to the REST resource. JAX-RS by default doesn't support PATCH hence Beadledom adds the support for PATCH explicitly.
For more details on the PATCH method visit the PATCH RFC_.
To use the PATCH method and annotation for your resource, simply annotate your JAX-RS resource method with the PATCH annotation as shown below
.. code-block:: java
@PATCH
@Path("path/to/patch")
@Produces(MediaType.APPLICATION_JSON)
public Response patch(
@PathParam("id") final Long id,
@ApiParam(value = "changes to make to the object with the specified id")
PatchObject patchObject);
.. _RFC: https://tools.ietf.org/html/rfc5789
@sparuvu comments addressed here. @b-boogaard I went with Sundeeps description of the annotation in the jaxrs.rst. Concise, simple and exactly what the user needs to know. I removed the git url that was linked in the description because don't see how it relates to PATCH at all... |
/** | ||
* Indicates that the annotated method responds to HTTP PATCH requests. | ||
* | ||
* @author John Leacox |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be you :) and not John
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you insist :) bb8be52
import javax.ws.rs.HttpMethod; | ||
|
||
/** | ||
* Indicates that the annotated method responds to HTTP PATCH requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may be - Annotation to support the Http PATCH requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current description is consistent with other jaxrs http annotation descriptions https://docs.oracle.com/javaee/7/api/javax/ws/rs/PUT.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to matching the jaxrs descriptions.
docs/source/manual/jaxrs.rst
Outdated
PATCH | ||
-------------- | ||
|
||
`PATCH is a HTTP verb (similar to GET, POST, DELETE, PUT) to push partial changes to the REST resource. JAX-RS by default doesn't support PATCH hence Beadledom adds the support for PATCH explicitly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, it would be good if we could link the PATCH to this wiki article - https://en.wikipedia.org/wiki/Patch_verb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
link to wiki on brian's version of rst f388ee2
I think I like what Brian has. It is more detailed and more importantly it points that implementing services have the freedom to implement whatever PATCH algorithm they want to go with. |
@@ -4,4 +4,5 @@ | |||
<suppress files="generated-sources" checks=".*"/> | |||
<suppress files="generated-test-sources" checks=".*"/> | |||
<suppress files="com.cerner.beadledom.client.resteasy.ApacheHttpClient4Dot3Engine" checks=".*"/> | |||
<suppress files="com.cerner.beadledom.jaxrs.PATCH" checks="AbbreviationAsWordInName" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just want to confirm this is necessary because checkstyle is expecting the classname to be Patch
?
If JAX-RS hadn't already set the standard for these annotations we would name it that way, but PATCH
is correct in following the standard of the other JAX-RS annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep that is the reason.
/** | ||
* Indicates that the annotated method responds to HTTP PATCH requests. | ||
* | ||
* @author Eric Christensen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add @since 2.5
below author.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to @b-boogaard's doc text. |
Will it be desired for beadledom to include a class with additional mediatypes like json-patch and json-merge-patch that can be used similarly to This questions came to mind while looking at this review, but I think it would be a separate code change if it is desired. |
@johnlcox we are planning to use json-merge-patch in our application so yes I would say that is a desired behavior. |
I think adding the media types for patch is a good idea. |
Is there any reason that adding the media types could not be done in this code change? |
I'd rather see it as a separate code change because I think there needs to be some discussion on the strategy we want to use for supporting additional media types in general. This probably warrants starting with an issue for that discussion prior to any code changes. |
+1 |
1 similar comment
+1 |
I logged #37 for the media type discussion. |
+1 |
1 similar comment
+1 |
What was changed? Why is this necessary?
From issue 21 JAX-RS does not have a PATCH annotation for supporting HTTP patch method like it does for others like GET or POST. We should add a PATCH annotation that can be used for handling the patch HTTP method.
How was it tested?
The PATCH annotation was tested by consuming this change in a test branch of a project that already consumes beadledom. In this project, a simple resource that uses the PATCH annotation was used to manually make sure that the behavior performed as expected. Two unit tests were also added to the project to 1. Ensure that PATCH is used and behaves as expected and 2. PATCH is used and performs an operation on the server to ensure that serialization works as expected.
How to test
mvn clean install -U
Reviewers