• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Should I create a Repository interface and Models based on the end points in a REST app?

 
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am new to Spring Boot and rusty in REST...

Now, I am tasked to created several end points based on the following tags:



My question is :

Should I create a Store repository interface or Do I create an Order repository interface and then I do it like this ;



Or should I create a Order repository interface  and then I do it like this



Assuming the later is to be used, I would need to have a entity class Store right ?

Thanks.
 
Saloon Keeper
Posts: 15528
364
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Design repositories and web APIs separately. While REST resources may often look like database entities, there are cases where they don't map to each other well.

A StoreRepository only makes sense if you save individual pet stores in a database.

Your REST API doesn't make sense to me. A POST request on a path /store/inventory implies to me that you will be adding an entire inventory to a store, not placing an order for a pet.

It also doesn't make sense to me that you would use a Pet instance as an ID to get an Order from your repository. Instead, I would expect the OrderRepository to look something like this:
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Design repositories and web APIs separately. While REST resources may often look like database entities, there are cases where they don't map to each other well.

A StoreRepository only makes sense if you save individual pet stores in a database.

Your REST API doesn't make sense to me. A POST request on a path /store/inventory implies to me that you will be adding an entire inventory to a store, not placing an order for a pet.



I think I better provide the various end points to be more clear:

But, really, I am blur myself...



I have left out all the common findbyId in /pet/ end point.

Hope you could advise me if there is any change in terms of the Repository interface I should create.

Many thanks for your help again.

 
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You may find this tutorial helpful. You can create a repository class extending the CrudRepository .
https://www.concretepage.com/spring-5/spring-data-crudrepository-example
 
Stephan van Hulst
Saloon Keeper
Posts: 15528
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The endpoints you described do not form a REST API. It's just plain RPC. I'm not saying that's bad, it's fine. It's just not REST.

Based purely on the request URL paths, you'll want at least a PetController and an OrderController, and maybe an InventoryController. For instance, the PetController could look like this (when using JAX-RS):

Note that I made up the classes FormDataUtilities and InvalidFormDataImageException, they are not part of any framework I know of.

Anyway, as you can see from this example controller, it assumes that there is a PetRepository interface that contains methods findByStatuses() and findById() that return Collection<Pet> and Optional<Pet> respectively, and a method addImage().

Only make repository interfaces for entire object graphs that you want to store. For instance, even if you have a separate table in your database that stores images, don't create an ImageRepository because you'll only ever want to store or retrieve an image related to another specific object in your database, such as a pet. You'll probably want a PetRepository and an OrderRepository, and you'll probably want an InventoryRepository as well that stores the inventory of a store.

I'm not sure what your supervisor expects of the GET /store/inventory endpoint, but I imagine it would return a response like this:

Such a controller could look like this:
 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For the above example, in Spring, we use @Autowired to inject the PetRepository.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:The endpoints you described do not form a REST API. It's just plain RPC. I'm not saying that's bad, it's fine. It's just not REST.

Based purely on the request URL paths, you'll want at least a PetController and an OrderController, and maybe an InventoryController. For instance, the PetController could look like this (when using JAX-RS):



Oh no....cos I actually tweaked a sample Spring REST project to fit into this requirements.

The sample project I used is :

https://projects.spring.io/spring-petclinic/#quick-start

And the this project will be using JPA so I have used extened JpaCRUDRepository in all my interfaces.  Is it ok to do it that way ?

Furthermore, I am thinking of later abstracting out the common findById across all the entities by using


SpEL Expressions as outlined in 5.3.7 at https://docs.spring.io/spring-data/jpa/docs/current/reference/html/@reference

Cos there are so many CRUD and I am thinking just replacing it with a T<CRUD>(Note: I am pretty new in this but I have seen people doing it this way)



But, I am still struggling with the basic skeleton to get even the base up and running cos I find that there seems to be a tight coupling with the sample that downloaded from Spring site as in there is a validation maven plug in and if you added new entities then it is not going to run.  I spent yesterday night fixing that.

I hope you can let me have some clue if I am on the right direction in doing this project. Tks.

Also, later on I will be adding User log in function with session and really I am not sure how this piece fit together...it seems more like a MVC app to me...correct me if I am wrong...


/user/createWithList:
   post:
     tags:
     - "user"
     summary: "Creates list of users with given input array"
     description: ""
     operationId: "createUsersWithListInput"
     produces:
     - "application/xml"
     - "application/json"

/user/login:
   get:
     tags:
     - "user"
     summary: "Logs user into the system"
      operationId: "loginUser"
 
     parameters:
     - name: "username"
       in: "query"
       description: "The user name for login"
       required: true
       type: "string"
     - name: "password"
       in: "query"
       description: "The password for login in clear text"
       required: true
       type: "string"



And since it is written creates list of users with given input array I supposed this is a hardcoded function with List<User> add UserName blah blah blah

Hope to have your guidance Stephan and many thanks for your help.

 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:You may find this tutorial helpful. You can create a repository class extending the CrudRepository .
https://www.concretepage.com/spring-5/spring-data-crudrepository-example



Hi Himai,

Just to clarify, using this would be not different from using Spring Boot right ?
Or I still have to use Spring Initizlizer to generate all the libraries that are needed before I try to use it in my case?
 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Targara,
The CrudRepository can be used in Spring boot / Spring framework.
You can use Spring intializer to generate a Spring boot project and add some child classes for CrudRepository.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi, Targara,
The CrudRepository can be used in Spring boot / Spring framework.
You can use Spring intializer to generate a Spring boot project and add some child classes for CrudRepository.



Hi Himai Minh,

I would like to further check with you cos I found out that there is this petstore that has very similar end points like what I am doing now but they are using ResponseContext to return the response.


https://github.com/swagger-api/swagger-petstore/blob/master/src/main/java/io/swagger/petstore/controller/PetController.java



Is this the right way to do a RPC web app?

Can I use javax.ws.rs-api to do it ?

And if I don't do the testing like what they do using Petdata, do I just use a public void main (String []) and then I just create an instance of Pet and do a getId, getName like that is it ok ?

Furthermore, I'd like to clarify should I use the below code for /store/order


cos I am not sure about this one...since I can't tell if a user is supposed to be able to place an order just by looking at this description : /store/order and should I included Store as entity ?

Really, I am so confused really hope can get some help here....really I feel that maybe coding is not for me...

Tks.

 
Himai Minh
Bartender
Posts: 2419
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,Tanagara,
The PetController is not using any Spring's Restful features.
I am sure javax.ws.rs-api is from JEE,not Spring
In Spring , you can use ResponseEntity<>  to return the output.

You may want to use these as reference:
https://spring.io/guides/tutorials/rest/
https://www.baeldung.com/spring-response-entity
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi,Tanagara,
The PetController is not using any Spring's Restful features.
I am sure javax.ws.rs-api is from JEE,not Spring
In Spring , you can use ResponseEntity<>  to return the output.

You may want to use these as reference:
https://spring.io/guides/tutorials/rest/
https://www.baeldung.com/spring-response-entity



Thanks so much for the tutorial and I have used this guide and adapt accordingly.

But, another question came to my mind as I edit the PetController... cos for if I were to follow strictly the example in that swagger-petstore, I would just be getting a return in response as oppose to the traditional way of returning via GET, POST etc to return say an array of pets that has the same status for example.

I'd also want to clarify about java.ws.rs, cos in the utility of this petstore, they are also using import javax.ws.rs.core.MediaType so is it not advisable to use or it is ok to use?

Or ...I am sorry but I have problem in reading that swagger document...does it mean that I only need to return a response will do.  But then if it is just a response of ok or bad request, then what does this app serve the purpose then...so sorry but I really am not very good in this whole thing.

Thanks for your help in advance.
 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Tangara,
For MediaType, you can use org.spring.framework.http.MediaType. There are different types in this class, such as APPLICATION_JSON, APPLICATION_ATOM_XML and etc.
If you choose to use Spring framework, then stick with it and don't need to use JEE for Restful.

If can return ResponseEntity with a status such as new ResponseEntity<>( message, HttpStatus.OK) or new ResposneEntity<>(message, HttpStatus.BAD_REQUEST) and etc.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi, Tangara,
For MediaType, you can use org.spring.framework.http.MediaType. There are different types in this class, such as APPLICATION_JSON, APPLICATION_ATOM_XML and etc.
If you choose to use Spring framework, then stick with it and don't need to use JEE for Restful.

If can return ResponseEntity with a status such as new ResponseEntity<>( message, HttpStatus.OK) or new ResposneEntity<>(message, HttpStatus.BAD_REQUEST) and etc.



Hi Himai,

That part is easy but the utility part if I were to use Spring HTTP headers I am afraid with my beginner level it is really tough to refactor.

I google abit and found this one at

https://stackoverflow.com/questions/62372402/spring-how-to-pass-automatically-https-header-between-microservices

Do you think this is the thing I should use or can you give me some hints how to refactor the utility part to accept json and xml using header request in Spring.
Tks.
 
Himai Minh
Bartender
Posts: 2419
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Spring, your request is converted into Json by default.
You pass in a customized object type to a method, it will be converted into JSON by Spring.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:In Spring, your request is converted into Json by default.
You pass in a customized object type to a method, it will be converted into JSON by Spring.



Thanks Himai,

Could you advise me at what stage people start to test out or do they test out Rest Controller at all ?  Or do I just use the RestClient as per your recommend article to do it.

I have often heard people using Postman or Curl or even Swagger to test out the end point so I just hope to have some advice where to start ?

Furthermore, I have tried using that sample app and modified accordingly to use Spring library as suggested by you.

However, there is this pets.add(createPet) that I can't get into the RespondEntity and Request Context, I hope you can let me know if there is a better way to do it other than using the PetData.

Thanks again for your help.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi, Tangara,
For MediaType, you can use org.spring.framework.http.MediaType. There are different types in this class, such as APPLICATION_JSON, APPLICATION_ATOM_XML and etc.
If you choose to use Spring framework, then stick with it and don't need to use JEE for Restful.

If can return ResponseEntity with a status such as new ResponseEntity<>( message, HttpStatus.OK) or new ResposneEntity<>(message, HttpStatus.BAD_REQUEST) and etc.



Hi Himai,

I need further clarification as  I noted that I am mixing RequestContext request in this ResponseEntity and I am not sure if it is alright to do that.  I just want to make sure that everything is correct, since you said don't sue JAX-RS.

Here'a a snippet of code


You advice is greatly appreciate.

 
Himai Minh
Bartender
Posts: 2419
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can try and see if that works.
 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also, one more note. I think you only need to pass the integer id to the delete method. You don't need the RequestContext.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:

Himai Minh wrote:You may find this tutorial helpful. You can create a repository class extending the CrudRepository .
https://www.concretepage.com/spring-5/spring-data-crudrepository-example




Hi Himai,

I refer to the above recommended sample.

Now, I am facing problem in using Postman to test my SpringBoot, as it keeps giving me

CORS error : the request has been blocked because of CORS policy


and I have been trying for days how to resolve this without avail...I used annotations like @CrossOrigin at the Controller and a the method, removing all the security config files etc, etc..still cannot

So, now I tried out using RESTclient like what is is mentioned in this article.

But, I am not getting any result either.

How do I run this RESTClient ?

Futhermore, I am still trying to get SpringBoot to connect to MYSQL(fumbled till now...)

so I test out using hard-coded Status :



Hope you could share with me

1) what should I do to get rid of the CORS error by Postman
2) how to run the SpringBoot with the RestClientUitl to see the result ?

Thank you once again for your help.

 
Stephan van Hulst
Saloon Keeper
Posts: 15528
364
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Do you understand what CORS is in the first place? Do you understand what causes CORS issues?

What request are you making in Postman? Can you show us the controller action that you expect to be called?
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:You may find this tutorial helpful. You can create a repository class extending the CrudRepository .
https://www.concretepage.com/spring-5/spring-data-crudrepository-example



Hi Himai,

I need to further clarify with you as I am still very much confused with this RESTController.
While I am doing the various queries for all the methods now, I researched and ran into this article :


https://www.netsurfingzone.com/hibernate/temporal-annotation-example-in-hibernate-jpa-using-spring-boot-and-oracle/



Can I know why some people are using ResponseEntity and some use like this article return a book ?

Also, I noted alot of them do not use Service and ServiceImpl layer.

So, if I were to use ServiceImpl that has the implementation method whereas My service layer is an interface that contains the various methods without the implementation.
In the Controller, if I user service.method will it work ?

Because I compared this to the way I implemented using the servlet method, we will use a Factory to do service = new ServiceImpl

Please let me know what is the right ways of implementing a Rest Controller.

Thank you.

 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tangara,
You mean the difference between @Controller and @RestController?
@Controller is the C of the MVC architecture , which handles the update of model,M and dispatch the model to view V.
@RestController is also the controller , but with this annotation , all the methods don't need @ResponseBody.
https://www.baeldung.com/spring-controller-vs-restcontroller

Usually in a controller, it injects a service bean and the service bean interacts with the repository bean to access the database.

For the difference between @ResponseEntity and @ResponseBody:
http://zetcode.com/springboot/responseentity/#:~:text=ResponseEntity%20represents%20an%20HTTP%20response,add%20headers%20and%20status%20code.
https://goodwinwei.wordpress.com/2017/01/06/springresquestbody-responsebody-vs-httpentityresponseentity/
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi Tangara,
You mean the difference between @Controller and @RestController?
@Controller is the C of the MVC architecture , which handles the update of model,M and dispatch the model to view V.
@RestController is also the controller , but with this annotation , all the methods don't need @ResponseBody.
https://www.baeldung.com/spring-controller-vs-restcontroller

Usually in a controller, it injects a service bean and the service bean interacts with the repository bean to access the database.

For the difference between @ResponseEntity and @ResponseBody:
http://zetcode.com/springboot/responseentity/#:~:text=ResponseEntity%20represents%20an%20HTTP%20response,add%20headers%20and%20status%20code.
https://goodwinwei.wordpress.com/2017/01/06/springresquestbody-responsebody-vs-httpentityresponseentity/



Hi Himai,

Thanks for your reply.
Can I know whether it is important to put @Repository at our Repositories interface before Springboot can autowired and coordinated everything for it to work ?
cos I tried to put @Repository as per article below but Eclipse wouldn't allow it and I wonder if it is a Eclipse problem :-


Repository is a raw type.  References to generic type Repsository<T1, T2> should be parameterized



is there something I need to add in Eclipse ?

http://zetcode.com/springboot/repository/




Hope you could give me the right answer based on industry practice.

Tks.
 
Himai Minh
Bartender
Posts: 2419
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Tangara,
If your interface extends CrudRepository , then you don't need @Repository.
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Hi Tangara,
You mean the difference between @Controller and @RestController?
@Controller is the C of the MVC architecture , which handles the update of model,M and dispatch the model to view V.
@RestController is also the controller , but with this annotation , all the methods don't need @ResponseBody.
https://www.baeldung.com/spring-controller-vs-restcontroller

Usually in a controller, it injects a service bean and the service bean interacts with the repository bean to access the database.

For the difference between @ResponseEntity and @ResponseBody:
http://zetcode.com/springboot/responseentity/#:~:text=ResponseEntity%20represents%20an%20HTTP%20response,add%20headers%20and%20status%20code.
https://goodwinwei.wordpress.com/2017/01/06/springresquestbody-responsebody-vs-httpentityresponseentity/



Not exactly,  I wanted to know why there is different ways people write their RestController.

For example the latest one I found is using entityManager at


https://zetcode.com/java/eclipselink/



What is the correct way to implement a RestController ?

Cos the earlier link they just return the Entity object....and that's another way...so I am really confused.  I really don't have anybody to ask because I am told to google only.  
Does it work like that in this industry ?

Because I really take the words for real when I was told I would be mentored cos I really think that mentor is someone that knows a subject very well.

Or am I too naive in taking the words for real?
 
tangara goh
Ranch Hand
Posts: 1021
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Himai Minh wrote:Also, one more note. I think you only need to pass the integer id to the delete method. You don't need the RequestContext.



Hi Himai,

I need your advice again.
Say if this is not a deleteById method but a findById method.
And I havn't set up the db.
So, is it possible to just test the end point by using this method as per example:


https://github.com/spring-projects/spring-data-examples/blob/master/jpa/eclipselink/src/main/java/example/springdata/jpa/eclipselink/Application.java



cos I tried to use this example above but it is not successful :


@ComponentScan("com.petstore.repository.PetRepository")
//@EnableJpaRepositories(basePackageClasses = PetRepository.class)
//@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class MyPetStoreApplication {


private static final Logger LOG = LoggerFactory.getLogger(MyPetStoreApplication.class);

//@Autowired
//DataSourceProperties dataSource;

//@Autowired
//PetRepository petRepository;

public static void main(String[] args) { //

PetRepository petRepository = SpringApplication.run(MyPetStoreApplication.class, args).getBean(PetRepository.class);
petRepository.save(new Pet(1, "aaa"));
petRepository.save(new Pet(2, "bbb"));
}
//public  Pet(Integer petId, String name) {// I created another constructor just with 2 fields
}



So, if I remove the PetRepository petRepository for the auto-wiring, then it will give me error:


Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.petstore.repository.PetRepository' available.



I'm not sure by using this way to put in the test data, the end point will rendered result when testing with a rest client.

Hope you can let me know why I can't reproduce the same method using that example in Spring guide.

Thanks

 
Himai Minh
Bartender
Posts: 2419
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tangara,
I guess your PetRepository cannot be found because it is not in any subpackage of where the MyPetStoreApplication is.
For example, this may be the structure you need:

com
  -example
           - MyPetStoreApplication.java
           - repository
                 - PetRepository.java

@SpringBootApplication mean searching for components in the current package of com.example and sub packages of com.example.

I hope that will help.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic