restful-api最佳实践

简介:

Best-practices-for-a-pragmatic-restful-api

先阅读文档:http://www.oschina.net/translate/best-practices-for-a-pragmatic-restful-api 理解restful api设计理念

我们公司的所有微服务接口都放在 "api.998jk.com/微服务名" 下

微服务内部api设计规范为:业务域/访问级别, 与best-practices-for-a-pragmatic-restful-api的区别是加入了一级访问级别,例如:

简单列表接口 /chatMessage/pb GET方式,提交参数page,pageSize,total

复杂查询接口 /chatMessage/pb/search POST方式,提交参数为json RequestBody,根据各个接口不同自行定义

查询单条接口 /chatMessage/pb/123 GET方式,123为id

删除单条接口 /chatMessage/pt/123 DELETE方式,123为id

更新单条接口 /chatMessage/pt/123 PUT方式,提交参数为json RequestBody,根据各个接口不同自行定义

上述示例 完整路径为:api.998jk.com/微服务名/chatMessage/xxx

访问级别:

    pb(public) 公开,对外对内没有任何限制;

    pt(protected) 受保护,对外受保护,对内没有任何限制。需要header中含有authorization 值为"Bearer token令牌"。在api gateway会获取该token, 并且在header中设置uid 值为该令牌的用户id。

    df(default) 默认,对外加密,对内没有任何限制。继承protected限制。并且在api gateway会对返回结果加密,客户端需要对结果解密后使用。加密后json如下:

{"encrypted":"返回结果加密后的字符串"}

    pv(private) 私有的,对外无法访问,对内没有任何限制。继承default限制。

 

暴露的restful服务需采用JAX-RS标准注解,无需springMVC controller 直接暴露service,需要使用swagger注解以便自动产生restful api文档。示例如下

package charles.sc.provider.service;

import charles.sc.provider.entity.ChatMessage;
import com.jztey.framework.mvc.Paging;
import com.jztey.framework.mvc.RestfulPagingResult;
import com.jztey.framework.mvc.RestfulResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.cloud.netflix.feign.FeignClient;

import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

/**
 * Created by Charles on 2016/8/15.
 */
@FeignClient(value = "provider-service")
@Path("/chatMessage")
@Produces(MediaType.APPLICATION_JSON)
@Api(tags = {"聊天消息接口"})
public interface ChatMessageService {
    @Path("/pb")
    @GET
    @ApiOperation(value = "聊天记录列表", response = RestfulPagingResultChatMessage.class)
    RestfulPagingResult<ChatMessage> findPage(@QueryParam("id") int page, @QueryParam("pageSize") int pageSize, @QueryParam("total") int total);

    @Path("/pt/{id:\\d+}")
    @GET
    @ApiOperation(value = "按id查询聊天记录", response = RestfulResultChatMessage.class)
    RestfulResult<ChatMessage> find(@PathParam("id") Long id);

    @Path("/pb/search")
    @POST
    @ApiOperation(value = "搜索聊天记录", response = RestfulPagingResultChatMessage.class)
    RestfulPagingResult<ChatMessage> search(Paging<ChatMessage> paging);

    @Path("/pt")
    @POST
    @ApiOperation(value = "添加聊天记录", response = RestfulResultChatMessage.class)
    RestfulResult<ChatMessage> insert(@HeaderParam("uid") Long uid, @ApiParam @Valid ChatMessage chatMessage);

    @Path("/pt/{id:\\d+}")
    @DELETE
    @ApiOperation(value = "按id删除聊天记录", response = RestfulResultChatMessage.class)
    RestfulResult<ChatMessage> delete(@HeaderParam("uid") Long uid, @PathParam("id") Long id);

    @Path("/pt/{id:\\d+}")
    @PUT
    @ApiOperation(value = "修改聊天记录", response = RestfulResultChatMessage.class)
    RestfulResult<ChatMessage> update(@HeaderParam("uid") Long uid, @PathParam("id") Long id, @ApiParam @Valid ChatMessage chatMessage);

    class RestfulResultChatMessage extends RestfulResult<ChatMessage> {
    }

    class RestfulPagingResultChatMessage extends RestfulPagingResult<ChatMessage> {
    }
}

 

package charles.sc.provider.service;

import charles.sc.provider.entity.ChatMessage;
import com.jztey.framework.mvc.Paging;
import com.jztey.framework.mvc.RestfulPagingResult;
import com.jztey.framework.mvc.RestfulResult;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Charles on 2016/8/16.
 */
@com.alibaba.dubbo.config.annotation.Service
@Service
public class ChatMessageServiceImpl extends BaseService<ChatMessage> implements ChatMessageService {

    @Override
    public RestfulPagingResult<ChatMessage> findPage(int page, int pageSize, int total) {
        System.out.println("get");
        // 统一使用查询接口
        Paging<ChatMessage> paging = new Paging<>(page, pageSize);
        paging.setTotal(total);

        return this.search(paging);
    }

    @Override
    public RestfulResult<ChatMessage> find(Long id) {
        System.out.println("getById");
        return new RestfulResult(new ChatMessage(id, "fu", "tu", "msg", "mi", System.currentTimeMillis(), System.currentTimeMillis(), ChatMessage.STATUS_NO_PROCESS));
    }

    @Override
    public RestfulPagingResult<ChatMessage> search(Paging<ChatMessage> paging) {
        System.out.println("search");
        List<ChatMessage> entityList = new ArrayList<>();

        entityList.add(new ChatMessage(1L, "fu", "tu", "msg", "mi", System.currentTimeMillis(), System.currentTimeMillis(), ChatMessage.STATUS_NO_PROCESS));
        entityList.add(new ChatMessage(2L, "fu2", "tu2", "msg2", "mi2", System.currentTimeMillis(), System.currentTimeMillis(), ChatMessage.STATUS_NO_PROCESS));

        if (-1 == paging.getTotal()) {    // total没有传上来
            // 查询total
            paging.setTotal(100);
        }
        return new RestfulPagingResult(entityList, paging.getTotal());
    }

    @Override
    public RestfulResult<ChatMessage> insert(Long uid, ChatMessage chatMessage) {
        System.out.println("insert uid:" + uid);
        return new RestfulResult<>(chatMessage);
    }

    @Override
    public RestfulResult<ChatMessage> delete(Long uid, Long id) {
        System.out.println("delete uid:" + uid);
        return new RestfulResult(new ChatMessage(id, "fu", "tu", "msg", "mi", System.currentTimeMillis(), System.currentTimeMillis(), ChatMessage.STATUS_NO_PROCESS));
    }

    @Override
    public RestfulResult<ChatMessage> update(Long uid, Long id, ChatMessage chatMessage) {
        System.out.println("update uid:" + uid);
        return new RestfulResult<>(chatMessage);
    }
}

完整代码参考:http://gitlab.998jk.com/heying/spring-cloud





      本文转自yushiwh 51CTO博客,原文链接:http://blog.51cto.com/yushiwh/1942254,如需转载请自行联系原作者



相关文章
|
15小时前
|
应用服务中间件 API nginx
使用Python和Flask构建RESTful Web API
使用Python和Flask构建RESTful Web API
5 0
|
4天前
|
API
1天搞定SpringBoot+Vue全栈开发 (2)RESTful API与Swagger
1天搞定SpringBoot+Vue全栈开发 (2)RESTful API与Swagger
|
7天前
|
JSON 测试技术 API
pyhttptest 与 RESTful API 测试的完全指南
现在,无论是开发还是使用服务,我们每个人都面临着 REST API 的挑战。同时,我们正处于微服务的流行时代,我们将业务逻辑拆分为多个独立的小服务。这些服务大多遵循 RESTful 原则,并使用 JSON 格式进行通信,因为其简单性使其成为最广泛使用的格式。
|
7天前
|
缓存 测试技术 API
构建高效可扩展的RESTful API:后端开发的实践指南
【5月更文挑战第21天】 在现代Web开发领域,构建一个高效、可扩展且易于维护的RESTful API是至关重要的任务。本文将深入探讨如何利用最佳实践和先进技术栈来设计和实现一个健壮的后端服务。我们将讨论API设计原则、数据库优化策略、缓存机制、负载均衡以及容器化部署等方面,旨在为后端开发者提供一套全面的指导方案。
|
8天前
|
缓存 API 数据库
构建高效Python Web应用:Flask框架与RESTful API设计原则
【5月更文挑战第20天】 在现代Web开发中,构建一个轻量级且高效的后端服务至关重要。本文将深入探讨如何使用Python的Flask框架结合RESTful API设计原则来创建可扩展和易于维护的Web应用程序。我们将通过分析Flask的核心特性,以及如何利用它来实现资源的合理划分、接口的版本控制和请求处理优化等,来指导读者打造高性能的API服务。文中不仅提供了理论指导,还包括了实践案例,旨在帮助开发者提升开发效率,并增强应用的稳定性和用户体验。
|
8天前
|
Web App开发 存储 开发框架
使用Node.js构建RESTful API
【5月更文挑战第20天】本文指导使用Node.js和Express构建RESTful API。首先确保安装了Node.js,然后初始化项目,安装Express框架。在`app.js`中创建API,定义GET路由`/api/users`返回用户列表。运行服务器并测试API,最后讨论如何扩展API和提升其功能。这是一个构建RESTful API的基础入门教程。
|
12天前
|
网络协议 JavaScript 安全
第十一篇 前沿趋势与展望:深入探索GraphQL、RESTful API、WebSocket、SSE及QUIC与HTTP/3
第十一篇 前沿趋势与展望:深入探索GraphQL、RESTful API、WebSocket、SSE及QUIC与HTTP/3
|
12天前
|
存储 缓存 JSON
第九篇 API设计原则与最佳实践
第九篇 API设计原则与最佳实践
|
13天前
|
存储 缓存 监控
利用Python和Flask构建RESTful API的实战指南
在当今的软件开发中,RESTful API已成为前后端分离架构中的核心组件。本文将带你走进实战,通过Python的Flask框架,一步步构建出高效、安全的RESTful API。我们将从项目初始化、路由设置、数据验证、错误处理到API文档生成,全方位地探讨如何构建RESTful API,并给出一些实用的最佳实践和优化建议。
|
13天前
|
存储 缓存 API
构建高效的RESTful API:后端开发的实践指南
【5月更文挑战第14天】 在现代Web开发领域,构建可靠且易于维护的后端服务至关重要。本文将详细探讨如何通过最佳实践和常用技术栈来构建一个高效的RESTful API。我们将涵盖API设计原则、数据库交互优化、缓存策略、安全性考虑以及性能监控等关键方面。通过本文的指导,读者将能够理解并实现一个符合工业标准且响应迅速的后端系统。