Simon Ritchie

Ranch Hand
+ Follow
since Jul 16, 2015
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Simon Ritchie

Hi all,

After several years of professional Java development, I've decided to take the Oracle Certified Associate exam.  I'm posting here because I figure if I publicly announce it then it provides additional motivation for me to start studying. So far, I've subscribed to a Udemy course on passing the exam and I've also purchased the Practice Tests book from Scott Selikoff and Jeanne Boyarsky, which looks excellent.  Hopefully in a few months I'll be able to return here and say I've passed but in the meantime wish me luck!
Thanks Tim.

I should have stated that I'm actually leaving a startup to join this new one.  But the difference is that the old startup was based around a monolithic back-end.  The reason I left was largely personal - I found the tech architect and the scrum leader to be impatient and unhelpful at times.  But I did make the mistake of diving into the code and making changes without fully understanding what it did and how it worked.  I don't want to repeat that mistake (or any other mistake) this time around.
4 years ago
Hi everyone,

Next month I'll be starting in a new role as a mid-level Java developer with a successful startup.  The architecture is a microservices design, which is something I've a couple of years experience in thanks to a similar role I once had with a large multinational.  I'm keen to start well in the new role so I thought I'd ask some advice here.

What is the best way you've found to come up to speed on a new codebase?  Are there any tips or recommendations?  I've always found the first couple of months in a new role intimidating because, on top of all of the new technologies you've to become familiar with, you're also confronted with this massive codebase that's often difficult to understand.
4 years ago
That's a thoughtful response, thank you.  I've some further questions, if that's alright.

Junilu Lacar wrote:I think the wrapper concept is not appropriate here. It's abstracting at the wrong level.



What would you recommend I use instead?  I thought I only had two choices when it comes to using a RestTemplate -
1) creating a wrapper class to contain the response
2) mapping the response to a Map<String, Object>

I went with the wrapper approach because I thought the alternative (using a Map) would lead to lots of code where I would have to pick through the map looking for properties with specific names and then try and map those properties to DTOs or POJOs, etc.  

Junilu Lacar wrote:In similiar situations, I would try to figure out a design where I only need to add new classes instead of adding new methods to an existing class to support additional domain types.



Do you think then that a better design would be to have a separate class (with its own RestTemplate) for each external API call instead of cramming them all into one service as I've done here?  It makes sense but it leads to more classes...

Junilu Lacar wrote:The design would also either allow configuration-based registration of the new domain classes or have some way of discovering domain classes as they are added to the system. If you go the discovery route, it would also adapt the system when types have been removed or obsoleted.



Oh, that's interesting.  So basically, design it in such a way that on application startup the code should get the format of the responses from a configuration file?
4 years ago

Junilu Lacar wrote:What's definitely smelly to me are all these classes that extend BaseWrapper. What are you "wrapping" with these classes anyway?



I'm wrapping the responses from a third party API.

Junilu Lacar wrote:What do you gain from making all these classes extend BaseWrapper?



Each of the response objects from the four different APIs I'm calling are different.  But they will all have a HttpStatus, a text field containing a description of the HttpStatus (i.e. "404 Not Found") and then, if the there was an error on the client side, a list of MyErrorDTO objects.  So rather than have those fields duplicated in the wrappers for the Dog, Cat, Crocodile APIs I thought they could all extend a base wrapper class to avoid duplication.

Junilu Lacar wrote:How can a DogWrapper be in the same class hierarchy as an ErrorWrapper?



Yes, that's a good point.

Junilu Lacar wrote:Also, what exactly is your understanding of "clean code"? For me, the basic qualities of clean code is that it makes sense, that it's intent is clear, and that it's easy to work with. At the very least, the clarity of intent quality is lacking in this code.



My understanding would be the same as yours in that clean code should first of all be easy to understand, should avoid unnecessary duplication and be easy to maintain.  I acknowledge that this code I've written is not very clear, which is why I decided to put it up for review.  I had toyed with the idea of writing four different methods, one for each client API call, but I thought this would lead to duplication of code where I was calling the RestTemplate.  I thought "Why not just have a generic method that calls the RestTemplate and then convert the response data to the relevant wrapper?"


4 years ago

Rob Spoor wrote:You can use @RequestParam this way, or you can use them for each query / form parameter separately. For instance, @RequestParam("fromDate") String fromDate, @RequestParam("toDate") String toDate. You may even be able to change the type now, and have Spring convert the strings for you.



Yeah, I've always used @RequestParam for each parameter separately, which is why I was confused by the use of the Map.
4 years ago
That's a Swagger annotation.  I forgot to remove it before posting the code.
4 years ago
Thanks, Dave.  Those are not the only two parameters that are passed but they are the only two mandatory ones, I should say for the record.
4 years ago
Hi folks,

The project I’m working on has a REST API endpoint /api/v1/exportreport.  It’s simple enough - it allows users to specify a date range and will produce a response containing data within the specified range that is then exported to a CSV file.

I’m a little confused by how the parameterisation of the endpoint has been written.  By viewing the call made by the front-end code in the console of the browser I’m using, I can see that it’s calling the endpoint with these parameters



That’s all fine.  However here is the Java code in the controller that handles this request



That “parameters” map is what’s confusing me.  The code is working (I’ve tested it via the front-end) but I don’t know how or where the “fromDate” and “toDate” parameters are being slotted into a Map.  Is this something that Spring Boot does behind the scenes?  Furthermore, do you think this is good design?  I’ve not shown the code that validates the parameters contained in the Map (basically, there is a configurable list of required parameters for this endpoint, which the service checks to see if they’re present in the Map) but the contents of the Map are used to build a query that is executed using a JdbcTemplate.
4 years ago
Hi folks,

There’s a third-party API with four endpoints that I’ve written a service class to interact with.  For the purposes of the example let’s say the endpoints are

/api/v1/dogs
/api/v1/cats
/api/v1/ducks
/api/v1/crocodiles

Each of the four endpoints are called using a RestTemplate and I’ve written a separate “wrapper” POJO to interpret the response from each endpoint.  Each of these four POJOs extends a base wrapper class that has three properties - a HttpStatus variable, a String variable that contains potential HTTP response error descriptions and a List<> of custom POJOs that I’m mapping errors to.  So my wrapper classes look like this











The third-party APIs are written in such a way that if anything other than a 2xx response is sent, they will respond with a JSON array of error objects, so I’ve also created a wrapper for this response too




Here is my service class that does all of the heavy lifting of calling these external endpoints.  I’ve left out the import statements and the MyCustomException code as I think it’s probably enough to understand how the code works without seeing those




Despite the fact that this is the best I could do, I’m not happy in the slightest.  There are a number of problems.  First, I tried to make the class as generic as possible, which is why I delegated all the RestTemplate calls to a single method called getResponse() that returns a generic ResponseEntity object.  But this has had the effect of making all of the methods getDogs, getCats, getDucks, getCrocodiles look the same if not very similar, which could confuse another developer.

Secondly, I don’t think I’m using generics very well here.  Can someone enlighten me and tell me if it could be improved on?

Thirdly, I’m not too sure that using two methods ensure…() to throw exceptions is clean code.  For a start, despite the fact that if the responseEntity.getBody() method returns null then a MyCustomException will be thrown but my IDE still says that setting the HttpStatus variable in the get…Wrapper() methods might still produce a NullPointerException.  Why is that?

There are probably dozens of things wrong with this class but I really want to learn and want to know what is the best way to write a service that calls an external REST API.  Any help would be welcome.
4 years ago
Hi folks,

What is the best practice for storing application properties for different tenants in a multi-tenant Spring Boot application?

I’m working on a Spring Boot project with a multi-tenant architecture.  All of the tenants use the same database with the same schema but have an identifying column in each table, i.e.: tenant_id

Several features of the application make use of properties loaded from YAML files, of which there is one YAML for each tenant.  This YAML contains the properties unique to that tenant.  The application has a service that locates these YAML files on the classpath, reads their properties into memory and then applies these properties to POJOs that are passed into one of the service methods.

My question is around best practices for multi-tenant application properties as I’ve not found an example online.  Is there a standard way of storing application properties for different tenants?  Is using separate application properties or YAML files the best option or would it be better to store these in a database?
4 years ago
Hi all,

I’ve written a method to get the number of n-grams of a specified size n from a String.  For example, the number of 2-grams in the sentence “How now brown cow” is 3:

How now
now brown
Brown cow

Here is my method:





My concern is that the nested for loop here might adversely affect performance and that there would be a faster, more memory-efficient way to perform this operation.  Are there any suggestions?  Or are there any common libraries out there that perform this function that I've overlooked?
5 years ago
Hi all,

I’m developing for a microservice application.  There are several different microservices but all of them use the same database.  I’ve been presented with a user story that requires querying data saved by one microservice (A) and enriching it from another microservice (B).  As I understand it, in a true microservices architecture this should be done by making an API call from B to A using something like a RestTemplate or HttpClient.  But seeing as the tables that contain the information I need are accessible to B from the database, is it a better design decision to simply write a DAO that gets the data I need?
6 years ago