A web service is a method of communication between multiple devices over the World Wide Web. Using Web Services, we can publish application's functions to everyone. In the web services world, REpresentational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URLs. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods.
- To create a resource on the server, use POST .
- To retrieve a resource, use GET .
- To change the state of a resource or to update it, use PUT .
- To remove or delete a resource, use DELETE .
Earlier we have discussed implementation process of Restfulwebservice app using CXF JAX-RS services. This time I decided to implement microservices. Regarding microservices architecture I have followed my development/design experiences and microservice Io. It will be great if readers share their own experiences and point of view on the topic microservices architecture. To keep it simple in this blog instruction will we will discuss implementation steps. Regarding spring boot application I followed amazining documentation provided by spring io spring Io.
I have also deployed this example app on cloud systems like Heroku and RedHat Openshift. So readers can explore them real-time. Demostration application services are available at
- -> @Heroku
- -> @RedhatOpenshift.
-
Required Software
- Developemnt
- Testing
- spring-boot-starter 1.5.6
- spring-boot-starter-web 1.5.6
- spring-boot-starter-web 1.5.6
- spring-boot-starter-cache 1.5.6
- spring-boot-autoconfigure 1.5.6
- spring-boot-starter-aop 1.5.6
- spring-boot-starter-security 1.5.6
- spring-boot-starter-logging 1.5.6
- spring-boot-starter-actuator 1.5.6
- ehcache
- log4j
- springfox-swagger2
⇢ Domain Layer
Application Layer
@Cacheable(value = "employeeCache", key = "#id", sync = true) @Override @LogMethodExecution public Employee getEmployee(Integer id) { return employees.get(id); }The employee id is used as a key of cache. by using sync=true arguments we trigger spring caching technology to sync the object state only if there is any change. 2. getEmployees method
@Cacheable(value = "employeeCache", sync = true) @LogMethodExecution public CollectiongetEmployees() { return employees.values(); }
⇢ Interface Layer
Method Name | HTTP Method | url mapping | description |
getEmployees | GET | "/employee/services/listOfEmployee" | fetch list employee detail avilable in system |
getEmployee | GET | "/employee/services/employeeDetail" | fetch employee detail by id |
addEmployees | POST | "/employee/services/addEmployee" | Add Employee |
updateEmployee | PUT | "/employee/services/updateEmployee" | Employee details update. |
deleteEmployee | DELETE | "/employee/services/deleteEmployee" | Employee deletion |
Method Name | Security | Annotation |
getEmployees | ROLE_ADMIN | @PreAuthorize("hasAuthority('ROLE_ADMIN')") |
getEmployee | ROLE_ADMIN | @PreAuthorize("hasAuthority('ROLE_ADMIN')") |
addEmployees | ROLE_ADMIN | @PreAuthorize("hasAuthority('ROLE_ADMIN')") |
updateEmployee | ROLE_ADMIN | @PreAuthorize("hasAuthority('ROLE_ADMIN')") |
deleteEmployee | ROLE_ADMIN | @PreAuthorize("hasAuthority('ROLE_ADMIN')") |
import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Authorization;
- Secnario 1 Roles based authentication using url. (using inMemoryAuthentication)
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { /* * Scenario 1. using inMemoryAuthentication */ auth.inMemoryAuthentication().withUser("admin").password("admin@123").roles("ADMIN"). // Admin user and().withUser("user1").password("user@123").roles("USER"). // local user and().withUser("kaustuv").password("pass@123").roles("USER", "ADMIN"); // Myself having both } @Override protected void configure(HttpSecurity http) throws Exception { // Scenario 1. url path configuration. http.httpBasic().and().authorizeRequests().antMatchers("/employee/**").hasRole("ADMIN").antMatchers("/**") .hasRole("USER").and().csrf().disable().headers().frameOptions().disable(); // maximum session allowed session http.sessionManagement().maximumSessions(5).sessionRegistry(sessionRegistry()); }
- Scenario 2 Roles based authentication using method level Annotation (@EnableGlobalMethodSecurity) using custom authentication provider.
@Autowired RestAppAuthenticationProvider restAppAuthenticationProvider; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { /* * Scenario 2. Example of AuthenticationProvider */ auth.authenticationProvider(restAppAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { // Scenario 2. this configuration is for method level configuration. http.httpBasic().and().authorizeRequests().anyRequest().authenticated().and().csrf().disable().headers() .frameOptions().disable(); // maximum session allowed session http.sessionManagement().maximumSessions(5).sessionRegistry(sessionRegistry()); }
⇢ Application Configuration Layer
⇢ Spring Boot App Runner
- Build the application using following maven command
- Once the build is done. use following command to start the spring boot application.
- After sucessfull deployment services will be available at http://localhost:8080
- Use following command to start the spring boot application in debug mode.
Post Development deployment
$ mvn clean install
$ java -jar target/com.kaustuv.spring.example.boot.rest-0.0.1-SNAPSHOT.jar
$ java -Ddebug -jar target/com.kaustuv.spring.example.boot.rest-0.0.1-SNAPSHOT.jar
Post Deployment testing
Load following soapui project file in soap ui app. and Execute testcases. Reader can use swagger html page as well to test the apis.
Source Code
- References:
EhCache
swagger2
http://www.baeldung.com
Soapui
http://www.baeldung.com
European Union laws require you to give European Union visitors information about cookies used on your blog. In many cases, these laws also require you to obtain consent.
As a courtesy, we have added a notice on your blog to explain Google's use of certain Blogger and Google cookies, including use of Google Analytics and AdSense cookies.