restful在项目中的应用总结

restful 开发规范

1.URL命名规则:

1.1. URL命名原则

1、  URL请求采用小写字母,数字,部分特殊符号(非制表符)组成。

2、  URL请求中不采用大小写混合的驼峰命名方式,尽量采用全小写单词,如果需要连接多个单词,则采用连接符“_”连接单词

1.2. URL分级

第一级Pattern为模块,比如组织管理/orgz, 网格化:/grid

第二级Pattern为资源分类或者功能请求,优先采用资源分类

 

1.3. CRUD请求定义规范(RESTful)

如果为资源分类,则按照RESTful的方式定义第三级Pattern,

RESTful规范中,资源必须采用资源的名词复数定义。

 

 

/orgz/members

GET

获取成员列表

/orgz/members/120

GET

获取单个成员

/orgz/members

POST

创建成员

/orgz/members/120

PUT

修改成员

/orgz/members

PUT

批量修改

/orgz/members/120

PATCH

修改成员的部分属性

/orgz/members/120

DELETE

删除成员

 

1.4. 复杂查询请求定义规范(RESTful)

 

/module/tickets?state=open

GET

过滤

/module/tickets?sort=-priority

GET

排序

/module/tickets?sort=-priority,created_at

GET

排序

/module/tickets?sort=-updated_at

GET

排序

/module/tickets?state=closed&sort=-updated_at

GET

过滤+排序

/module/tickets?q=return&state=open&sort=-priority,created_at

GET

搜索+过滤+排序

/module/tickets/recently_closed

GET

一般数据请求

/module/tickets?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at

GET

指定返回列

/cars?offset=10&limit=5

GET

分页

2.CRUD对应操作的处理

2.1 created:PostMapping :  返回HttpStatus.created:201                                                                                                                                              retrieve: GetMapping     : 返回HttpStatus.ok:200  
      update:PutMapping     : 返回HttpStatus.created: 201                                                                                                                                                delete :DeleteMapping: 返回HttpStatus.noContent:204

3.用ResponseEntity对象封装返回值(以POST为例)
@PostMapping(value = "/learningPlays",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, 
                                                                produces =  MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<LearningPlayDto> createLearningPlay(@Valid @RequestBody LearningPlayDto toCreate) throws URISyntaxException {
        
String userId = SecurityUtil.getCurrentUserId().orElseThrow(() ->new InvalidTokenTypeException("Invalid token type. User                         token is needed."));
        toCreate.setCreator(userId);
        toCreate = learningPlayDtoMapper.map(learningPlayService.createLearningPlay(toCreate));
        return ResponseEntity.created(new URI("/learningPlays/" + toCreate.getId()))
                .headers(HeaderUtil.createEntityCreationAlert(Constants.LEARNING_PLAY_ENTITY_NAME, toCreate.getId()))
                .body(toCreate);
    } 
   
 
4.注意事项

4.1POST方法应该返回你增加的对象,包括id

4.2HeadUtil

public final class HeaderUtil {


    private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class);


    private static final String APPLICATION_NAME = "****";


    private HeaderUtil() {
    }


    public static HttpHeaders createAlert(String message, String param) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-CAPGENIE-ALERT", message);
        headers.add("X-CAPGENIE-PARAMS", param);
        return headers;
    }


    public static HttpHeaders createEntityCreationAlert(String entityName, String param) {
        return createAlert(APPLICATION_NAME + "." + entityName + ".created", param);
    }


    public static HttpHeaders createEntityUpdateAlert(String entityName, String param) {
        return createAlert(APPLICATION_NAME + "." + entityName + ".updated", param);
    }


    public static HttpHeaders createEntityDeletionAlert(String entityName, String param) {
        return createAlert(APPLICATION_NAME + "." + entityName + ".deleted", param);
    }


    public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) {
        log.error("Entity processing failed, {}", defaultMessage);
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-CAPGENIE-ERROR", "exception." + errorKey);
        headers.add("X-CAPGENIE-PARAMS", entityName);
        return headers;
    }

 4.3IdGenerator(插入数据库之前先生成id的方法)

public interface IdGenerator {

    long nextId();

}

4.4(调用nextId方法生成id)

import com.capgemini.genie.learningplay.service.IdGenerator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class SnowflakeIdGenerator implements IdGenerator {


    private Logger logger = LoggerFactory.getLogger(SnowflakeIdGenerator.class);


    private long microserviceId;
    private long machineId;
    private long sequence;


    public SnowflakeIdGenerator(long microserviceId, long machineId, long sequence){
        // sanity check for microserviceId
        if (microserviceId > maxMicroserviceId || microserviceId < 0) {
            throw new IllegalArgumentException(String.format("microservice Id can't be greater than %d or less than 0", maxMicroserviceId));
        }
        if (machineId > maxMachineId || machineId < 0) {
            throw new IllegalArgumentException(String.format("machine Id can't be greater than %d or less than 0", maxMachineId));
        }
        logger.warn("worker starting. timestamp left shift %d, machine id bits %d, microservice id bits %d, sequence bits %d, microservice id %d %n",
                timestampLeftShift, machineIdBits, microserviceIdBits, sequenceBits, microserviceId);


        this.microserviceId = microserviceId;
        this.machineId = machineId;
        this.sequence = sequence;
    }


    private long twepoch = 1522207715092L;


    private long microserviceIdBits = 8L;
    private long machineIdBits = 6L;
    private long maxMicroserviceId = -1L ^ (-1L << microserviceIdBits);
    private long maxMachineId = -1L ^ (-1L << machineIdBits);
    private long sequenceBits = 8L;


    private long microserviceIdShift = sequenceBits;
    private long machineIdShift = sequenceBits + microserviceIdBits;
    private long timestampLeftShift = sequenceBits + microserviceIdBits + machineIdBits;
    private long sequenceMask = -1L ^ (-1L << sequenceBits);


    private long lastTimestamp = -1L;


    public long getMicroserviceId(){
        return microserviceId;
    }


    public long getMachineId(){
        return machineId;
    }


    public long getTimestamp(){
        return System.currentTimeMillis();
    }


    @Override
    public synchronized long nextId() {
        long timestamp = timeGen();


        if (timestamp < lastTimestamp) {
            System.err.printf("clock is moving backwards.  Rejecting requests until %d.", lastTimestamp);
            throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds",
                    lastTimestamp - timestamp));
        }


        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }


        lastTimestamp = timestamp;
        return ((timestamp - twepoch) << timestampLeftShift) |
                (machineId << machineIdShift) |
                (microserviceId << microserviceIdShift) |
                sequence;
    }


    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }


    private long timeGen(){
        return System.currentTimeMillis();
    }
}


猜你喜欢

转载自blog.csdn.net/weixin_41830501/article/details/80800810