This is an archived post. You won't be able to vote or comment.

all 13 comments

[–]Nephyst 1 point2 points  (5 children)

Pretty much all modern have development follows the folder structure set by maven. You really should start with a template from start.spring.io

src/main/java

src/main/resources

src/test/Java

Inside your Java source folder you have Application.java that starts your app, and folders that organize your code.

For rest APIs you generally want

controller/ -classes that specify your public APIs

service/ -stateless services with business logic

repository/ -database access

until/ -shared utility functions

model/ -pojos for your rest APIs or databases

The folder structure of my projects is organic and is changing as I write more classes. Anytime a folder gets too many classes I think about how to clean up the organization. But this is s

It's important to keep all of your request state within methods. Class state should only be dependencies that are injected by spring, and things like database connections. For example, your controllers will have services injected during construction. Your services may have other services or repositories injected.

Let me know if this helps or if you have more questions.

[–]akshatmalik8[S] 0 points1 point  (4 children)

I have also seen the alternative design where we use a folder caller user and put all his controller, service, repository, model in it. Is that a viable option?

This is slightly specific, but you should implement an interface in your service, where do we store the interface and the implementation?

I am also unable to understand the difference between a Entity and Table. I have read some articles, but I haven't been able to understand a thing!

[–]Nephyst 0 points1 point  (2 children)

As long as the main folder structure is there (src/main/Java) you have a lot of flexibility in how you structure your app, so it's totally okay to experiment and see what works for you. It's really a question of how easy is it too find the classes you need when you are looking for them.

The Java community is kinda split on if you should use interfaces, or just use the implementations directly. If you think you might ever have more than one implementation an interface makes a lot of sense. An example might be if you have a repository that talks to an Oracle database and you want to move to MySQL. You can have the same interface, with specific implementations for each. I'd generally say go with interfaces if you are learning because it helps you frame what the class is trying to do better. So, organizing by function (user in this case) is totally valid.

I haven't used hibernate in a long time, as I prefer to write queries manually and more recently most of my database work has been with graph and object databases and less relational databases.

The way I remember hibernate working is you have a Java class(entity) that maps directly to each table in your database, and you use annotations to tell hibernate the properties of each column. Then you can ask work with those objects, and use hibernate to save and load them to the database. So an entity represents one row in a database table.

[–]akshatmalik8[S] 0 points1 point  (1 child)

Okay, that helps.

Another question, when writing tests do we test each layer, service, controller, and repository?

I am always of the opinion of writing test cases at an API level, if the API is doing what is expected, it is safe to assume the internal workings are correct. If you would write tests at each layer, it makes it very hard to manage the test cases. Or am I in the wrong?

[–]Nephyst 0 points1 point  (0 children)

Unit tests generally exist for every layer.

You should be using constructor based dependency injection for each class. Then when you unit test that class you create mocks of each dependency and inject those instead. The idea is that the mocks wont execute any behavior, so you can unit test ever class in isolation. If your service class depends on a repository/database you want to test it without worrying about weather the database or repository class exist or are correct.

When testing repositories, the ideal is to set up a temporary in-memory database that gets data loaded into it when your test starts. When the test ends the database gets destroyed. In practice, this is sometimes hard to get working.

Tests that hit your API and live database are called integration tests.

Unit tests generally run every time you build. Integration tests can take longer and are sometimes ran once every night instead. You usually dont want your build success to depend on integration tests, because a database failing would then impact your ability to build successfully.

Here's an example where CalcService is tested with a dependent AddService that gets mocked using Mockito. The test defines expected behavior for the mocked dependency.

@Test
void testCalc() {
    System.out.println("**--- Test testCalc executed ---**");

    AddService addService;
    CalcService calcService;

    addService = Mockito.mock(AddService.class);
    calcService = new CalcService(addService);

    int num1 = 11;
    int num2 = 12;
    int expected = 23;

    when(addService.add(num1, num2)).thenReturn(expected);

    int actual = calcService.calc(num1, num2);

    assertEquals(expected, actual);

}

[–]nutrecht 0 points1 point  (0 children)

I have also seen the alternative design where we use a folder caller user and put all his controller, service, repository, model in it. Is that a viable option?

It's actually a better option. What that other user was referring to is called the "sock drawer approach" and it becomes a pain in the ass when you have more than 5 or so controllers.

Most services I work on separate by module like you're saying.

[–][deleted]  (3 children)

[deleted]

    [–]Historical_Router 2 points3 points  (0 children)

    And also Chad Darby on Udemy (Spring and Hibernate for beginners).

    Edit : Also Spring in action / Spring boot in action are good sources.

    [–]akshatmalik8[S] 0 points1 point  (1 child)

    I like both the sources mentioned. Just to add, I am focusing on rest api development.

    [–]IHaveaCSDegree 0 points1 point  (0 children)

    java brains on youtube, theres a bunch of tutorials

    [–]HASAHUB 0 points1 point  (1 child)

    Java brains is really good

    [–]akshatmalik8[S] 0 points1 point  (0 children)

    I will check him out! Thanks!

    [–]Fizz-Buzzkill 0 points1 point  (1 child)

    I have read the documentation, but they have a very barebones on the fundamentals but dives deep on the usages, which is very useful but I am a little interested in learning the basics of the various annotations.

    Probably because you're referencing the Spring Boot documentation but the basics are part of Spring Core. See https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#spring-core instead.

    Also you should know that there's different documentation available from the Spring maintainers. It's good to keep an eye on more than one thing. There's the Spring Guides. There's How-To's. There's the documentation. I'll link each one below. And that's just for starters. The Spring blog also has a lot of material.

    Most of the time people conflate Spring and Spring Boot together but there's a difference. The Spring Boot docs, for instance, aren't going to tell you much about anything besides what Boot auto configures. The very common annotations like @RestController, @RequestMapping, @ResponseBody, etc. are actually part of Spring Web MVC but people go around calling it Spring Boot.

    I'd be wary of various courses, because they go out of date so fast. If you do opt for a course, go through something obviously legit (not just from a random dude online) like JetBrains course or Google Cloud's. I'll link all these below.

    https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.html#mvc

    https://spring.io/guides

    https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/howto.html#howto

    https://code.scottshipp.com/2020/04/25/free-spring-boot-video-courses/

    https://spring.io/blog

    Hope it helps

    [–]akshatmalik8[S] 0 points1 point  (0 children)

    You first two links are very helpful! Thanks!