-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[bravo-0013] Implement new payment API to receive payments by user id #25
base: main
Are you sure you want to change the base?
Conversation
…nal fixes, adding mapstruct to pom, cover by tests
I want to start by saying that we are not expecting any additional commits. Feel free to make them if you wish, but that's not an expectation that we have. With that said I will go through your changes and leave technical comments on them. |
<mysql.connector.version>8.0.24</mysql.connector.version> | ||
<orika.core.version>1.5.4</orika.core.version> | ||
<springfox.swagger2.version>2.5.0</springfox.swagger2.version> | ||
<springfox.swagger.ui.version>2.5.0</springfox.swagger.ui.version> |
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.
Nice clean up here.
@ResponseStatus(value = HttpStatus.NOT_FOUND) | ||
public ErrorDto handlePaymentNotFoundException(final PaymentNotFoundException exception){ | ||
log.info("Payments not found, details: {}", exception.getMessage()); | ||
var errorDto = new ErrorDto(); |
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.
errorDto
could be final
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.
Agree, thanks
import org.mapstruct.Mapping; | ||
import org.mapstruct.Named; | ||
|
||
@Mapper(componentModel = "spring") |
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.
Can you explain what componentModel = "spring"
means?
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.
@wheelerswebservices it means construct mapper as spring bean. Because mapper has different construction types, using factory, spring beans etc.
return payments.stream().map(this::convertPayment).collect(Collectors.toList()); | ||
} | ||
|
||
public PaymentDto convertPayment(final Payment payment){ |
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.
Can you elaborate on why the new PaymentMapper
class is superior to these methods within the existing ResourceMapper
class?
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.
@wheelerswebservices because mapperFacade, which is used here is not the flexible one from SOLID principles perpective.
First of all, if you would have 10 dto's which you need to map from the entity its not a good idea to create 20 methods inside ResourseMapper class.
Second, is that you need to implement all of the extra mapping, or when field names are different. In the Mapstruct its simple, you only need an interface, and specify everything only using annotations. Its very useful and simple to understand. Its flexible when you need some extra mappings, for example as was for card mask. So everything for this mapping is located only in 1 Java interface.
Thats why mapstruct is so popular today.
You could read all the details below: https://www.baeldung.com/java-performance-mapping-frameworks
private static final String MESSAGE = "Payment not found for user with id {0}"; | ||
|
||
public PaymentNotFoundException(String userId) { | ||
super(MessageFormat.format(MESSAGE, userId)); |
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 use
MessageFormat.format
instead ofString.format
? - Do you think this
MESSAGE
variable is really necessary as it's only used in 1 place?
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.
@wheelerswebservices regarding first: I don't think this is really matters
second: this exception is only related to Payment not found flow, so there is not reason to extract this message somewhere else.
|
||
@Data | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public class PaymentDto { |
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 annotate with Builder
, AllArgsConstructor
, and NoArgsConstructor
if they are not all being used?
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.
Builder used to simplify construction for testing. Since we use Builder, NoArgs and AllArgs constrcustors is required for MapStruct.
Ticket bravo-0013
What was changed:
Why did I decide to use userId as a Request Parameter?
For me it looks weird we would have a path variable, since then the endpoint should look like /users/{userId}/payments.
As was mentioned in the ticket, we need to use PaymentController, so the best practices would be using userId as request param.
Sometimes it depends on what we would have in the future.
Also there was a couple of things:
We could fetch payments by creating new repository interface, as I've done, but on the other hand the implementation could be: