Skip to content

analysis and reflection

Janne Tahkola edited this page Apr 26, 2024 · 25 revisions

Important information for final deadline

‼️  This chapter should be completed by final deadline (see course information at Lovelace)


📑  Chapter summary In this section we would like that you reflect about the work you have done during the course.

SECTION GOALS:

  • Reflect about own learning
  • Feedback on course instruction

✔️     Chapter evaluation (max 5 points) You can get a maximum of 5 points after completing the Analysis and Reflection section. More information in Lovelace return box for Final deadline.

Analysis and reflection

Future Work

📑  Content that must be included in the section Explain how you would improve your RESTful API and your client application. Try to develop the ideas, and explain why each improvement is needed

For the Users API, I would still split it further into users and authentication services. User management and authentication are related but not necessarily enough that it would conform to SRP.

I would also make roles and privileges dynamic instead of having them hard-coded in the Java code. Currently, roles are not in a database and cannot be modified, while privileges are in a database but also cannot be modified. Only the associations between than are modifiable. If they were both loaded from the database, they could also be more easily shown in the API documentation. Now it requires some trial and error to figure out which API you have access to - which is also fine, as it's a completely internal API. I did originally add the required roles into the API docs by reflecting to the @PreAuthorize annotations, but because they use SpEL, it's not worth it to start parsing it as I will do the dynamic roles/permissions later.

As for the client, I want to completely rewrite it. I got too tight on time and didn't have time to think about anything but making it work. There are no tests, hypermedia is not consumed much so the client is tied to the current URI structure, and it's overall difficult to read.

The UI design is fine so it's just about designing the code structure better.

Finally, for the Game API, I would probably think about merging more of the REST endpoints into the WebSocket API. There are some things like the status of the process which can be handled better with real-time communication than with polling a REST endpoint.


Lessons learnt

📑  Content that must be included in the section Discuss in this section the things that you would have done differently if you started the project after this course ends.

I would have started with the client earlier and chosen a different technology. I'm more familiar with Angular, and I prefer that it provides a project structure for you. I only chose React because I ran out of time and needed to get it done quickly, which React is good at.

I would've also started with hypermedia earlier. It was more of an afterthought, which can be seen both from the connectedness, HAL-FORMS templates as well as the lacklustre API Documentation for the hypermedia parts. I decided to add it just for the extra points, so my plan wasn't even to have a fully compliant and polished hypermedia support, but I still didn't quite get it where I wanted.

It was my first time doing any kind of comprehensive hypermedia API, so I underestimated how much work it would be. Spring's support for it is fine but it's not perfect. Once again relying on abstractions has its limitations, similar story with the Hibernate managed database I mentioned before.


Comments about the project

📑  Content that must be included in the section Comment where you encountered the main difficulties while doing your project work. Discuss about the easiest/most difficult parts of the project. Provide convincing statements.

Main difficulties were probably the previously mentioned Hibernate-based schema management and the hypermedia support with Spring HATEOAS.

Usually I create databases and queries myself, and use the most basic Hibernate annotations to link the Java classes to tables for the Hibernate Session. This time I wanted to finally delve deeper into what Hibernate can do if you let it do everything.

I started to like the fact that it can do almost everything for you, but as the system got more complicated I ran into restrictions. For example, I'm now using Hibernate to generate the initial schema when there are changes, but then export it and create it manually when I deploy the services. When you add Docker and Testcontainers into the mix, the ordering of operations gets messed up, so it's just easier to manage that part yourself. Something like Flyway would help with this further.

Regarding Spring HATEOAS, most of the issues I had came from the HAL and HAL-FORMS specs. One of these I mentioned before in the API implementation section (the issue with templated links).

Another issue I encountered was the template support in Spring's HAL-FORMS implementation, which seemed really weird to me. For example, a collection with a min/max size would be represented as a "range", which I would expect to refer to a range of numbers. But, as you can see from the spec, there is no collection type. Similarly, there isn't a proper way to render child objects.

All of this of course makes sense when you realise that the whole point of it is to generate HTML forms - not JSON schemas like some other hypermedia frameworks :) This just means that you should choose HAL-FORMS only when it's appropriate, or design your API for it.

As usual, a REST API may be designed in more than one way and choosing between these is not always easy. Originally I had a more complex PATCH endpoint for modifying the user-role and role-privilege associations, but Ivan suggested than it's better to split it into POST and DELETE. I thought about it and decided that it's more RESTful and went with it. This was a good decision as it made it at least a bit easier to communicate the API with HAL, due to the spec restrictions mentioned above. The downside of the current implementation is that each modifying operation must be applied to a single association at a time, but this could also be addressed in a few ways.

Another somewhat challenging thing was the Docker setup. I wanted to get rid of the Java dependency on the host, and to have SonarQube for code quality analysis for the Java code. I had issues with both the project setup and Docker networking. Project setup was easy enough to fix, won't go into it more here as it's just Maven specific things. Main achievement here is that now, only Docker is required on the host to deploy the whole system.

SonarQube is provided as another (optional) Docker service. During the build phase, you are not connected to Docker networks which is a problem when you want to upload reports into it during the build phase when all tests are ran. To solve this I used host network mode, meaning that I upload the reports to the SonarQube container via the host.

Testcontainers, which is a library I use to run PostgreSQL in a throwaway Docker container during integration tests, might lead you to think about Docker in Docker during the build phase when the tests are ran. However, you can also utilize the host's existing Docker API, which is a much lighter setup. This setup can be seen in the "production" Dockerfiles and Makefile of the palikka-api module.

One of the easier parts of the project was the main business logic in the Users API which, combined with Hibernate-generated SQL queries, was overall pretty quick to implement.


Comments about the course

📑  Content that must be included in the section Make sincere comments about the course. How this course could be improved? What should be changed? What should not be changed?

I think the requirement to use hypermedia to get full points could be loosened. It's mentioned even in the lecture material that most APIs are CRUD REST, and I also have not done such a deep dive into hypermedia in any job before.

All APIs I have worked with have been internal which is probably a major reason, but I still think there could be less focus on it. I also don't remember using any APIs from major companies like Google, Microsoft or Spotify that would've been hypermedia driven.

I appreciate the learning experience though, I didn't expect that hypermedia would be one of the most challenging parts of this project. Considering the exercise materials and HAL/HAL-FORMS specs I ended up reading, I feel that I learned a lot of useful things.

Focusing more on for example event-based systems, caching, authentication schemes, file storage or other (from my experience) more common patterns would be more useful than hypermedia. Many of these were touched in the exercises and offered as optional things to do, but I would put more focus on them. There is already a separate course for distributed systems so I won't mention that.

Having the return-everything-at-once track should not be changed, it offers a lot of flexibility. It could possibly use one more, maybe an optional, meeting with the staff.


Resources allocation

Task Student Estimated time
Everything Janne Tahkola ~1h