下面的API适用于对用户的CRUD操作及其相应的过滤器(某种规则)。这些过滤器基于用户对来自不同来源的传入数据应用,然后对数据进行各种转换。
我希望评审人员对设计、端点、异常处理和请求/响应进行评论。由于我正在学习设计REST,您的评论将有助于我在将来编写更好的API。
Data.class创建一个用户对象的静态列表,所有CRUD操作都在这个对象上执行,并从/到文件序列化/反序列化。
选择一个文件到DB的原因是现在数据非常小,而且项目正处于POC阶段。
package com.cisco.daas.filter.services;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.cisco.daas.configservice.entities.User;
import com.cisco.daas.configservice.utilities.FileOperations;
import com.cisco.daas.configservice.utilities.Operations;
public class Data {
private static final Operations<User> operations = new FileOperations<User>();
private static final List<User> users = new ArrayList<>();
public static List<User> getUsers() {
users.clear();
try {
users.addAll(operations.get());
} catch (IOException e) {
e.getMessage();
}
return users;
}
}接口:注释一次创建实体列表的方法的原因是因为我觉得它不优雅。如果想法不对,请告诉我。
package com.cisco.daas.filter.services;
import java.util.List;
import com.cisco.daas.configservice.entities.Filter;
public interface IFilterService {
void add(String userName,Filter filter);
//void add(String userName,List<Filter> filters);
Filter update(String userName, Filter filter);
void remove(String userName, String filterName);
List<Filter> getAll(String userName);
Filter getOne(String userName,String filterName);
}
package com.cisco.daas.filter.services;
import java.util.List;
import com.cisco.daas.configservice.entities.User;
public interface IUserService {
User add(User item);
//List<User> add(List<User> items);
User update(User item);
String remove(String userID);
List<User> query(String userID);
List<User> query();
}实现:
package com.cisco.daas.filter.services;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.cisco.daas.configservice.entities.Filter;
import com.cisco.daas.configservice.entities.User;
import com.cisco.daas.configservice.utilities.FileOperations;
import com.cisco.daas.configservice.utilities.Operations;
@Service
public class FilterService implements IFilterService {
private List<User> users = Data.getUsers();
private static final Operations<User> operations = new FileOperations<User>();
public FilterService() {
}
public void add(String userID, Filter filter) {
users.stream().filter(u -> u.getUserId().equals(userID)).forEach(x -> {
x.getFilters().add(filter);
});
try {
operations.save(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// public void add(String userID, List<Filter> filters) {
// users.stream().filter(u -> u.getUserId().equals(userID)).forEach(x -> {
// x.getFilters().addAll(filters);
// });
//
// try {
// operations.save(users);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
public Filter update(String userID, Filter filter) {
users.stream().filter(element -> element.getUserId().equals(userID) && element.getFilters().stream()
.filter(f -> f.getName().equals(filter.getName())).findAny().isPresent()).forEach(x -> {
x.getFilters().stream().forEach(s -> {
s.setCreatedOn(filter.getCreatedOn());
s.setDescription(filter.getDescription());
s.setEnabled(filter.isEnabled());
s.setFilterValue(filter.getFilterValue());
s.setReadOnly(filter.isReadOnly());
s.setModifiedOn(filter.getModifiedOn());
s.setName(filter.getName());
s.setType(filter.getType());
s.setValid(filter.isValid());
s.setEncrypted(filter.isEncrypted());
});
});
try {
operations.save(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return filter;
}
public void remove(String userID, String filterName) {
users.removeIf(element -> element.getUserId().equals(userID) && element.getFilters().stream()
.filter(f -> f.getName().equals(filterName)).findAny().isPresent());
try {
operations.save(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List<Filter> getAll(String userID) {
List<Filter> filters = users.stream().map(User::getFilters).flatMap(List::stream).distinct()
.collect(Collectors.toList());
return filters;
}
public Filter getOne(String userID, String filterName) {
java.util.function.Predicate<Filter> pred = p -> p.getName().equals(filterName);
List<Filter> filters = users.stream().map(User::getFilters).flatMap(List::stream).distinct()
.collect(Collectors.toList());
Optional<Filter> f = filters.stream().filter(pred).findFirst();
return f.get();
}
}
package com.cisco.daas.filter.services;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.cisco.daas.configservice.entities.Filter;
import com.cisco.daas.configservice.entities.User;
import com.cisco.daas.configservice.utilities.FileOperations;
import com.cisco.daas.configservice.utilities.Operations;
@Service
public class UserService implements IUserService {
private List<User> users = Data.getUsers();
private static final Operations<User> operations = new FileOperations<User>();
public UserService() {
}
public User add(User item) {
Optional<User> result = users.stream().filter(x -> item.getUserId().equals(x.getUserId())).findFirst();
if (!result.isPresent() || result == null) {
users.add(item);
for (User user : users) {
try {
operations.save(user);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
System.out.println("User already exist");
}
return item;
}
// public List<User> add(List<User> items) {
// Set<String> userids = items.stream().map(x -> x.getUserId()).collect(Collectors.toSet());
// List<User> present = users.stream().filter(x -> userids.contains(x.getUserId())).collect(Collectors.toList());
// List<User> notPresent = users.stream().filter(x -> !userids.contains(x.getUserId()))
// .collect(Collectors.toList());
//
// if (present.isEmpty()) {
// users.addAll(items);
// try {
// operations.save(users);
// } catch (IOException e) {
// e.printStackTrace();
// }
// } else if (!notPresent.isEmpty()) {
// users.addAll(notPresent);
// try {
// operations.save(users);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// return items;
//
// }
public User update(User item) {
users.forEach(element -> {
if (element.getUserId() == item.getUserId()) {
element.setUserId(item.getUserId());
element.setUserName(item.getUserName());
element.getFilters().forEach(filter -> {
Set<String> filters = item.getFilters().stream().map(f -> f.getName()).collect(Collectors.toSet());
List<Filter> present = item.getFilters().stream().filter(x -> filters.contains(x.getName()))
.collect(Collectors.toList());
List<Filter> notPresent = item.getFilters().stream().filter(x -> !filters.contains(x.getName()))
.collect(Collectors.toList());
if (present.isEmpty()) {
element.setFilters(item.getFilters());
} else {
element.getFilters().stream().forEach(filt -> {
present.stream().forEach(x -> {
if (filt.getName() == x.getName()) {
filt.setName(x.getName());
filt.setFilterValue(x.getFilterValue());
filt.setCreatedOn(x.getCreatedOn());
filt.setModifiedOn(x.getModifiedOn());
filt.setEnabled(x.isEnabled());
filt.setEncrypted(x.isEncrypted());
filt.setReadOnly(x.isReadOnly());
filt.setType(x.getType());
filt.setValid(x.isValid());
filt.setDescription(x.getDescription());
}
});
});
}
if (!notPresent.isEmpty()) {
element.setFilters(notPresent);
}
});
}
});
try {
operations.save(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return item;
}
public String remove(String userID) {
users.removeIf(x -> x.getUserId().equals(userID));
try {
operations.save(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return userID;
}
public List<User> query(String userID) {
List<User> result = null;
if (userID == null) {
System.out.println("User ID cannot be empty");
} else {
result = users.stream().filter(e -> e.getUserId().equals(userID)).collect(Collectors.toList());
}
return result;
}
public List<User> query() {
return users;
}
}对文件执行操作的实用程序类,如序列化/反序列化JSON:
package com.cisco.daas.configservice.utilities;
import java.io.IOException;
import java.util.List;
public interface Operations<T> {
void save(T serializableObject) throws IOException;
void save(List<T> serializableObjects) throws IOException;
List<T> get() throws IOException;
}
package com.cisco.daas.configservice.utilities;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.cisco.daas.configservice.entities.User;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
public class FileOperations<T> implements Operations<T> {
private ObjectMapper objectMapper;
// this is going to come from the property file.
private String filePath = "C:\\Users\\phyadavi\\workspace\\ConfigurationService\\src\\main\\resources\\seed.txt";
private File file;
// private T targetClass;
public FileOperations() {
this.objectMapper = new ObjectMapper();
this.file = new File(filePath);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.getMessage();
}
}
}
private void saveImpl(Object serializableObject) throws IOException {
String jsonData = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(serializableObject);
BufferedWriter br = new BufferedWriter(new FileWriter(file));
br.write(jsonData);
br.close();
}
@Override
public void save(List<T> serializableObjects) throws IOException {
saveImpl(serializableObjects);
}
@Override
public void save(T serializableObject) throws IOException {
saveImpl(serializableObject);
}
@Override
public List<T> get() throws IOException {
// JavaType type =
// objectMapper.getTypeFactory().constructCollectionType(ArrayList.class,
// targetClass.getClass());
// List<T> list = objectMapper.readValue(file, type);
List<T> list = objectMapper.readValue(file, new TypeReference<List<User>>() {
});
if (list == null) {
List<T> list1 = new ArrayList<T>();
return list1;
}
return list;
}
}实体:
package com.cisco.daas.configservice.entities;
import java.util.UUID;
public interface Entity {
String id = UUID.randomUUID().toString();
}
package com.cisco.daas.configservice.entities;
import java.util.List;
public class User implements Entity {
public User() {
}
private String userName;
private String userId;
private List<Filter> filters;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public List<Filter> getFilters() {
return filters;
}
public void setFilters(List<Filter> filters) {
this.filters = filters;
}
}
package com.cisco.daas.configservice.entities;
import java.util.Date;
public class Filter {
private String name;
private FilterValue value;
private String type;
private boolean encrypted;
private boolean readOnly;
private Date createdOn;
private Date modifiedOn;
private boolean valid;
private boolean enabled;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public FilterValue getFilterValue() {
return value;
}
public void setFilterValue(FilterValue value) {
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isEncrypted() {
return encrypted;
}
public void setEncrypted(boolean encrypted) {
this.encrypted = encrypted;
}
public boolean isReadOnly() {
return readOnly;
}
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public Date getModifiedOn() {
return modifiedOn;
}
public void setModifiedOn(Date modifiedOn) {
this.modifiedOn = modifiedOn;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
package com.cisco.daas.configservice.entities;
public class FilterValue {
private String filterId;
private String filterName;
private Condition condition;
private boolean action;
public String getFilterId() {
return filterId;
}
public void setFilterId(String filterId) {
this.filterId = filterId;
}
public String getFilterName() {
return filterName;
}
public void setFilterName(String filterName) {
this.filterName = filterName;
}
public Condition getCondition() {
return condition;
}
public void setCondition(Condition condition) {
this.condition = condition;
}
public boolean isAction() {
return action;
}
public void setAction(boolean action) {
this.action = action;
}
}
package com.cisco.daas.configservice.entities;
public class Condition {
private String field;
private Criteria criteria;
private String value;
private boolean isAdhering;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public Criteria getCriteria() {
return criteria;
}
public void setCriteria(Criteria criteria) {
this.criteria = criteria;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public boolean isAdhering() {
return isAdhering;
}
public void setAdhering(boolean isAdhering) {
this.isAdhering = isAdhering;
}
}
package com.cisco.daas.configservice.entities;
public enum Criteria {
IS,
CONTAINS,
GREATER_THAN,
LESSER_THAN;
}管制员:
package com.cisco.daas.configservice.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import com.cisco.daas.configservice.entities.User;
import com.cisco.daas.filter.services.IUserService;
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private IUserService userService;
@RequestMapping(value = "/users", method = RequestMethod.GET)
public @ResponseBody List<User> getAll() {
return userService.query();
}
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody List<User> getUser(@PathVariable(value = "id") String userid) {
return userService.query(userid);
}
@RequestMapping(value = "/users", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<HttpStatus> createUser(@Valid @RequestBody User user) {
userService.add(user);
return ResponseEntity.ok(HttpStatus.OK);
}
// @RequestMapping(value = "/users", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
// public ResponseEntity<HttpStatus> createUsers(@Valid @RequestBody List<User> entities) {
// @SuppressWarnings("unused")
// List<User> users = userService.add(entities);
// return ResponseEntity.ok(HttpStatus.OK);
// }
@RequestMapping(value = "/users", method = RequestMethod.PUT, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<User> updateUser(@Valid @RequestBody User entity) {
User user = userService.update(entity);
if (user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}
@RequestMapping(value = "/userid/{id}", method = RequestMethod.DELETE, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<HttpStatus> deleteUser(@PathVariable(value = "id") String userid) {
String result = userService.remove(userid);
if (result.equals(null)) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(HttpStatus.OK);
}
}
package com.cisco.daas.configservice.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.cisco.daas.configservice.entities.Filter;
import com.cisco.daas.filter.services.IFilterService;
@RestController
@RequestMapping("/api")
public class FilterController {
@Autowired
private IFilterService filterService;
@RequestMapping(value = "/users/{id}/filters", method = RequestMethod.GET, produces = {
MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody List<Filter> getAll(@PathVariable(value = "id") String userID) {
return filterService.getAll(userID);
}
@RequestMapping(value = "/users/{id}/filters/{filterName}", method = RequestMethod.GET, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Filter> getFilter(@RequestParam(value = "id", required = true) String userID,
@PathVariable(value = "filterName") String filterName) {
Filter filter = filterService.getOne(userID, filterName);
if (filter == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(filter);
}
@RequestMapping(value = "/users/{id}/filters", method = RequestMethod.POST, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<HttpStatus> createFilter(@PathVariable(value = "id") String id,
@Valid @RequestBody Filter filter) {
filterService.add(id, filter);
return ResponseEntity.ok(HttpStatus.OK);
}
// @RequestMapping(value = "/users/{userID}/filters", method = RequestMethod.POST, produces = {
// MediaType.APPLICATION_JSON_VALUE })
// public ResponseEntity<HttpStatus> createFilters(@PathVariable(value = "id") String userID,
// @Valid @RequestBody List<Filter> filters) {
// filterService.add(userID, filters);
// return ResponseEntity.ok(HttpStatus.OK);
// }
@RequestMapping(value = "/users/{userID}/filters", method = RequestMethod.PUT, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Filter> updateUser(@PathVariable(value = "id") String userID,
@Valid @RequestBody Filter entity) {
Filter filter = filterService.update(userID, entity);
if (filter == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(filter);
}
@RequestMapping(value = "/userid/{id}/filters/{filterName}", method = RequestMethod.DELETE, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<HttpStatus> deleteUser(@PathVariable(value = "id") String userid,
@PathVariable(value="filterName") String filterName) {
filterService.remove(userid, filterName);
return ResponseEntity.ok(HttpStatus.OK);
}
}主修班:
package com.cisco.daas;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages="com.cisco.daas")
public class ConfigurationServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigurationServiceApplication.class, args);
}
}发布于 2017-11-08 19:18:25
我希望这属于你所要求的设计领域。这些是我唯一能想到的建议。对于您的端点或异常处理,我没有真正有用的评论,因为它们看起来非常简单,而且我认为没有什么问题。
我建议用构造函数注入代替字段自动加载。而不是:
@Autowired
private IFilterService filterService;用途:
private final IFilterService filterService;
@Autowired
public FilterController (IFilterService filterService) {
this.filterService = filterService;
}这里解释了这一点:http://olivergierke.de/2013/11/why-field-injection-is-evil/
您还可以将@RequestMapping(method = RequestMethod.PUT)替换为@PutMapping,因为即时查看使用的是哪种方法要容易一些,尽管两者的工作原理完全相同。
我建议查看https://projectlombok.org/,让自己添加类级注释(如@Getter @Setter ),并保存一些样板代码。它还有很多其他的功能,网站有更多的信息。(注意:据我所知,JDK9仍然不受支持)
https://codereview.stackexchange.com/questions/179942
复制相似问题