Adding abstractions for CRUD APIs.
Now we can easily add controllers for any resource quickly by simply adding a few files.
This commit is contained in:
parent
f7aaafacfb
commit
8ccd001652
|
|
@ -27,15 +27,15 @@ public class SecurityConfig {
|
|||
@Bean
|
||||
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||
return http
|
||||
.csrf().disable()
|
||||
.formLogin().disable()
|
||||
.httpBasic().disable()
|
||||
.csrf().disable()
|
||||
.formLogin().disable()
|
||||
.httpBasic().disable()
|
||||
// .authenticationManager(reactiveAuthenticationManager)
|
||||
// .securityContextRepository(securityContextRepository)
|
||||
.authorizeExchange()
|
||||
.anyExchange().permitAll()
|
||||
.and()
|
||||
.logout().disable()
|
||||
.build();
|
||||
.authorizeExchange()
|
||||
.anyExchange().permitAll()
|
||||
.and()
|
||||
.logout().disable()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ public interface Url {
|
|||
String BASE_URL = "/api";
|
||||
String VERSION = "/v1";
|
||||
String WIDGET_URL = BASE_URL + VERSION + "/widgets";
|
||||
String TENANT_URL = BASE_URL + VERSION + "/tenants";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,38 @@
|
|||
package com.mobtools.server.controllers;
|
||||
|
||||
public abstract class BaseController {
|
||||
import com.mobtools.server.domains.BaseDomain;
|
||||
import com.mobtools.server.dtos.ResponseDto;
|
||||
import com.mobtools.server.services.CrudService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class BaseController<S extends CrudService, T extends BaseDomain, ID> {
|
||||
|
||||
private final S service;
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public Mono<ResponseDto<T>> create(@Valid @RequestBody T resource) {
|
||||
return service.create(resource)
|
||||
.map(created -> new ResponseDto<>(HttpStatus.CREATED.value(), created, null));
|
||||
}
|
||||
|
||||
@GetMapping("")
|
||||
public Flux<ResponseDto<T>> getAll() {
|
||||
return service.get()
|
||||
.map(resources -> new ResponseDto<>(HttpStatus.OK.value(), resources, null));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Mono<ResponseDto<T>> update(@PathVariable ID id, @RequestBody T resource) throws Exception {
|
||||
return service.update(id, resource)
|
||||
.map(updatedResource -> new ResponseDto<>(HttpStatus.OK.value(), updatedResource, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package com.mobtools.server.controllers;
|
||||
|
||||
import com.mobtools.server.constants.Url;
|
||||
import com.mobtools.server.domains.Tenant;
|
||||
import com.mobtools.server.dtos.ResponseDto;
|
||||
import com.mobtools.server.services.TenantService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(Url.TENANT_URL)
|
||||
public class TenantController extends BaseController<TenantService, Tenant, String> {
|
||||
|
||||
private final TenantService tenantService;
|
||||
|
||||
public TenantController(TenantService tenantService) {
|
||||
super(tenantService);
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
@GetMapping("/{name}")
|
||||
public Mono<ResponseDto<Tenant>> getByName(@PathVariable String name) {
|
||||
return tenantService.getByName(name)
|
||||
.map(widget -> new ResponseDto<>(HttpStatus.OK.value(), widget, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,32 +4,22 @@ import com.mobtools.server.constants.Url;
|
|||
import com.mobtools.server.domains.Widget;
|
||||
import com.mobtools.server.dtos.ResponseDto;
|
||||
import com.mobtools.server.services.WidgetService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(Url.WIDGET_URL)
|
||||
@RequiredArgsConstructor
|
||||
public class WidgetController extends BaseController {
|
||||
public class WidgetController extends BaseController<WidgetService, Widget, String> {
|
||||
|
||||
private final WidgetService widgetService;
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public Mono<ResponseDto<Widget>> create(@Valid @RequestBody Widget widget) {
|
||||
return widgetService.create(widget)
|
||||
.map(createdWidget -> new ResponseDto<>(HttpStatus.CREATED.value(), createdWidget, null));
|
||||
}
|
||||
|
||||
@GetMapping("")
|
||||
public Flux<ResponseDto<Widget>> getAllWidgets() {
|
||||
return widgetService.get()
|
||||
.map(widgets -> new ResponseDto<>(HttpStatus.OK.value(), widgets, null));
|
||||
public WidgetController(WidgetService service) {
|
||||
super(service);
|
||||
this.widgetService = service;
|
||||
}
|
||||
|
||||
@GetMapping("/{name}")
|
||||
|
|
@ -37,11 +27,4 @@ public class WidgetController extends BaseController {
|
|||
return widgetService.getByName(name)
|
||||
.map(widget -> new ResponseDto<>(HttpStatus.OK.value(), widget, null));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Mono<ResponseDto<Widget>> update(@PathVariable String id, @RequestBody Widget widget) throws Exception {
|
||||
return widgetService.update(id, widget)
|
||||
.map(updatedWidget -> new ResponseDto<>(HttpStatus.OK.value(), updatedWidget, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.mobtools.server.repositories;
|
||||
|
||||
import com.mobtools.server.domains.Tenant;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
public interface TenantRepository extends BaseRepository<Tenant, String> {
|
||||
Mono<Tenant> findByName(String name);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.mobtools.server.repositories;
|
||||
|
||||
import com.mobtools.server.domains.User;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends BaseRepository<User, String> {
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import org.springframework.stereotype.Repository;
|
|||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
public interface WidgetRepository extends BaseRepository<Widget, Long> {
|
||||
public interface WidgetRepository extends BaseRepository<Widget, String> {
|
||||
|
||||
Mono<Widget> findByName(String name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,72 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.mobtools.server.domains.BaseDomain;
|
||||
import com.mobtools.server.repositories.BaseRepository;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class BaseService {
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BaseService<R extends BaseRepository, T extends BaseDomain, ID> implements CrudService<T, ID> {
|
||||
|
||||
final Scheduler scheduler;
|
||||
|
||||
private final MongoConverter mongoConverter;
|
||||
|
||||
private final ReactiveMongoTemplate mongoTemplate;
|
||||
|
||||
private final R repository;
|
||||
|
||||
public BaseService(Scheduler scheduler,
|
||||
MongoConverter mongoConverter,
|
||||
ReactiveMongoTemplate reactiveMongoTemplate,
|
||||
R repository) {
|
||||
this.scheduler = scheduler;
|
||||
this.mongoConverter = mongoConverter;
|
||||
this.mongoTemplate = reactiveMongoTemplate;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<T> update(ID id, T resource) throws Exception {
|
||||
if (id == null) {
|
||||
throw new Exception("Invalid id provided");
|
||||
}
|
||||
|
||||
Query query = new Query(Criteria.where("id").is(id));
|
||||
|
||||
DBObject update = getDbObject(resource);
|
||||
|
||||
Update updateObj = new Update();
|
||||
Map<String, Object> updateMap = update.toMap();
|
||||
updateMap.entrySet().stream().forEach(entry -> updateObj.set(entry.getKey(), entry.getValue()));
|
||||
|
||||
return mongoTemplate.updateFirst(query, updateObj, resource.getClass())
|
||||
.flatMap(obj -> repository.findById(id))
|
||||
.subscribeOn(scheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<T> get() {
|
||||
return repository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<T> create(T widget) {
|
||||
return repository.save(widget);
|
||||
}
|
||||
|
||||
private DBObject getDbObject(Object o) {
|
||||
BasicDBObject basicDBObject = new BasicDBObject();
|
||||
mongoConverter.write(o, basicDBObject);
|
||||
return basicDBObject;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.BaseDomain;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface CrudService<T extends BaseDomain, ID> {
|
||||
|
||||
Flux<T> get();
|
||||
|
||||
Mono<T> create(T resource);
|
||||
|
||||
Mono<T> update(ID id, T resource) throws Exception;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.Tenant;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface TenantService extends CrudService<Tenant, String> {
|
||||
|
||||
Mono<Tenant> getByName(String name);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.Tenant;
|
||||
import com.mobtools.server.repositories.TenantRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
|
||||
@Service
|
||||
public class TenantServiceImpl extends BaseService<TenantRepository, Tenant, String> implements TenantService {
|
||||
|
||||
private final TenantRepository repository;
|
||||
|
||||
@Autowired
|
||||
public TenantServiceImpl(Scheduler scheduler,
|
||||
MongoConverter mongoConverter,
|
||||
ReactiveMongoTemplate reactiveMongoTemplate,
|
||||
TenantRepository repository) {
|
||||
super(scheduler, mongoConverter, reactiveMongoTemplate, repository);
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Tenant> getByName(String name) {
|
||||
return repository.findByName(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.User;
|
||||
|
||||
public interface UserService extends CrudService<User, String> {
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.User;
|
||||
import com.mobtools.server.repositories.UserRepository;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl extends BaseService<UserRepository, User, String> implements UserService {
|
||||
|
||||
public UserServiceImpl(Scheduler scheduler,
|
||||
MongoConverter mongoConverter,
|
||||
ReactiveMongoTemplate reactiveMongoTemplate,
|
||||
UserRepository repository) {
|
||||
super(scheduler, mongoConverter, reactiveMongoTemplate, repository);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,9 @@
|
|||
package com.mobtools.server.services;
|
||||
|
||||
import com.mobtools.server.domains.Widget;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface WidgetService {
|
||||
public interface WidgetService extends CrudService<Widget, String> {
|
||||
|
||||
Mono<Widget> getByName(String name);
|
||||
|
||||
Flux<Widget> get();
|
||||
|
||||
Mono<Widget> create(Widget widget);
|
||||
|
||||
Mono<Widget> update(String id, Widget widget) throws Exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,81 +2,32 @@ package com.mobtools.server.services;
|
|||
|
||||
import com.mobtools.server.domains.Widget;
|
||||
import com.mobtools.server.repositories.WidgetRepository;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WidgetServiceImpl extends BaseService implements WidgetService {
|
||||
public class WidgetServiceImpl extends BaseService<WidgetRepository, Widget, String> implements WidgetService {
|
||||
|
||||
private WidgetRepository widgetRepository;
|
||||
|
||||
private final MongoConverter mongoConverter;
|
||||
|
||||
private final ReactiveMongoTemplate mongoTemplate;
|
||||
|
||||
@Autowired
|
||||
public WidgetServiceImpl(Scheduler scheduler, WidgetRepository widgetRepository, MongoConverter mongoConverter, ReactiveMongoTemplate mongoTemplate) {
|
||||
super(scheduler);
|
||||
public WidgetServiceImpl(Scheduler scheduler,
|
||||
MongoConverter mongoConverter,
|
||||
ReactiveMongoTemplate mongoTemplate,
|
||||
WidgetRepository widgetRepository) {
|
||||
super(scheduler, mongoConverter, mongoTemplate, widgetRepository);
|
||||
this.widgetRepository = widgetRepository;
|
||||
this.mongoConverter = mongoConverter;
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Widget> getByName(String name) {
|
||||
return widgetRepository.findByName(name);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Widget> get() {
|
||||
return widgetRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Widget> create(Widget widget) {
|
||||
|
||||
return widgetRepository.save(widget);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Widget> update(String id, Widget widget) throws Exception {
|
||||
if (id == null) {
|
||||
throw new Exception("Invalid id provided");
|
||||
}
|
||||
|
||||
Query query = new Query();
|
||||
query.addCriteria(Criteria.where("id").is(id));
|
||||
|
||||
Update updateObj = new Update();
|
||||
|
||||
// DBObject update = getDbObject(widget);
|
||||
// Map<String, Object> updateMap = update.toMap();
|
||||
// updateMap.entrySet().stream().forEach(entry -> {
|
||||
// updateObj.set(entry.getKey(), entry.getValue());
|
||||
// });
|
||||
updateObj.set("name", "testName");
|
||||
mongoTemplate.updateFirst(query,updateObj, Widget.class);
|
||||
return widgetRepository.save(widget);
|
||||
|
||||
}
|
||||
|
||||
private DBObject getDbObject(Object o) {
|
||||
BasicDBObject basicDBObject = new BasicDBObject();
|
||||
mongoConverter.write(o, basicDBObject);
|
||||
return basicDBObject;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user