[For Arnon Rotem-Gal-Oz’s Article:http://dobbscodetalk.com/index.php?option=com_myblog&show=CRUD-is-bad-for-REST.html&Itemid=29]In one of my previous posts (Rest: good, bad and ugly), I made a passing comment, about how I think using CRUD in RESTful service is a bad practice. I received a few comments / questions asking why do I say that – so what’s wrong with CRUD and REST?
On the surface, it seems like a very good fit (both technically and architecturally), however scratch that surface, and you’d see that it isn’t a good fit for either.
REST over HTTP is the most common (almost only) implementation of the REST architectural style - to the point REST over HTTP is synonymous with REST. I would say most of the people who think of REST in CRUD terms, think about mapping of the HTTP verbs.
CRUD which stands for Create, Read, Update and Delete, are the four basic database operations. Some of the HTTP verbs, namely POST, GET, PUT and DELETE (there are others like OPTIONS or HEAD) seem to have a 1-1 mapping to CRUD. As I said earlier they don’t. The table below briefly contrast HTTP verbs and CRUD
Verb | CRUDdy Candidate | Actually |
GET | SELECT (Read) | Get a representation of a resource. While it is very similar to SELECT it also has a few features beyond an out-of-the-box SELECT e.g. by using If-Modified-Since (and similar modifiers) you might get an empty reply. |
Delete | Delete | Maps well |
PUT | Update | Put looks like an update but it isn’t since: 1. You have to provide a complete replacement for the resource (again similar to update but not quite) 2. You can use PUT to create a resource (when the URI is set by the client) |
POST | Insert | It can be used to create a but it should be a child/subordinate one. Furthermore, it can be used to provide partial update to a resource (i.e. not resulting in a new URI) |
OPTIONS | ? | Get the available ways to continue considering the current state or the resource |
HEAD | ? | Get the headers or metadata about the resource (which you would otherwise GET) |
The way I see it, the HTTP verbs are more document oriented than database oriented (which is why document databases like CouchDB are seamlessly RESTful). In any event, what I tried to show here is that while you can update, delete and create new resources the way you do that is not exactly CRUD in the database sense of the word – at least when it comes to using the HTTP verbs.
However, the main reason CRUD is wrong for REST is an architectural one. One of the base characteristics(*) of REST is using hypermedia to externalize the statemachine of the protocol (a.k.a. HATEOS– Hypertext as the engine of state). The URI to URI transition is what makes the protocol tick (the transaction implementation by Alexandros discussed in the previous post shows a good example of following this principle).
Tim Ewald explains this nicely (in a post from 2007…) :
… Here's what I came to understand. Every communication protocol has a state machine. For some protocols they are very simple, for others they are more complex. When you implement a protocol via RPC, you build methods that modify the state of the communication. That state is maintained as a black box at the endpoint. Because the protocol state is hidden, it is easy to get things wrong. For instance, you might call Process before calling Init. People have been looking for ways to avoid these problems by annotating interface type information for a long time, but I'm not aware of any mainstream solutions. The fact that the state of the protocol is encapsulated behind method invocations that modify that state in non-obvious ways also makes versioning interesting.
The essence of REST is to make the states of the protocol explicit and addressableg by URIs. The current state of the protocol state machine is represented by the URI you just operated on and the state representation you retrieved. You change state by operating on the URI of the state you're moving to, making that your new state. A state's representation includes the links (arcs in the graph) to the other states that you can move to from the current state. This is exactly how browser based apps work, and there is no reason that your app's protocol can't work that way too. (The ATOM Publishing protocol is the canonical example, though its easy to think that its about entities, not a state machine.)
If you are busy with inserting and updating (CRUDing) resources you are not, in fact, thinking about protocols or externalizing a State machine and, in my opinion, miss the whole point about REST.
CRUD services leads and promoted to the database as a service kind of thinking (e.g. ADO.NET data services) which as I explained in another post last year is a bad idea since:
- It circumvents the whole idea about "Services" - there's no business logic.
- It is exposing internal database structure or data rather than a thought-out contract.
- It encourages bypassing real services and going straight to their data.
- It creates a blob service (the data source).
- It encourages minuscule demi-serices (the multiple "interfaces" of said blob) that disregard few of the fallacies of distributed computing.
- It is just client-server in sheep's clothing.
The main theme of this and the previous post is that if we try to drag REST to the same old, same old stuff we always did we wouldn’t really get that many benefits. In fact, the “old” ways of doing that stuff are probably more suitable for the job anyway since they have been in use for a while now. and they are “tried and tested” (“You can’t win an argument with an idiot, he’ll just drag you down to his level and beat you with experience” …). REST is just a different paradigm that RPC, ACID transactions and CRUD.
* I know I sound like a broken record on that but our industry has a history diluting terms to a point they almost stop being useful (SOA comes to mind..). The way I see it you can have 3 levels on your way to REST over HTTP:
-
You can be using HTTP and XML/JSON – this is level 1 or “Using standards”.
-
You can be using the HTTP verbs properly and/or applying document oriented communications – this is level 2 or “Rest-like” interface
-
You can conform to all REST constraints and be at level 3 or “RESTful”.
All levels can be useful and bring you merit but only the 3rd is REST
相关推荐
本教程主要针对初学者,讲解如何在Spring MVC中实现RESTful CRUD操作。 1. **RESTful原则** RESTful设计的核心原则是将Web服务视为一组可标识的资源,每个资源都有一个唯一的URI。通过HTTP方法对这些资源进行操作...
使用SpringMVC+jdbctemplate实现REST风格的CRUD功能 完成功能:能够对用户进行CRUD操作,界面粗糙,只做演示 运行环境:eclipse2019.03+JDK8+Tomcat9.0.41+MySQL5.5 运用到的技术:spring+springMVC+jdbctemplate+...
本项目"crud-koa-rest"旨在演示如何使用Koa.js实现RESTful API,以处理CRUD操作。我们将深入探讨这个项目中的关键知识点。 首先,让我们了解Koa.js。Koa.js是由Express.js团队创建的,它的目标是提供更简洁、更强大...
当我们谈论“CRUD REST API”时,我们指的是通过RESTful API来实现对资源的创建、读取、更新和删除功能。 在Java世界中,实现CRUD REST API通常会使用Spring Boot框架,因为它提供了强大的工具和库来简化这个过程。...
【标题】"crud_django:带CRUD表的Django REST" 这个项目是关于使用Django框架构建RESTful API的示例,特别是涉及到CRUD(创建、读取、更新、删除)操作。CRUD是数据库操作的核心,对于任何Web应用程序来说都是必不...
CRUD,全称为Create(创建)、Read(读取)、Update(更新)和Delete(删除),是数据库操作的基础,也是理解任何数据驱动应用的核心概念。在IT行业中,CRUD操作广泛应用于各种应用程序,从简单的数据库管理工具到...
通过这个项目,你可以学习如何使用Django REST框架实现CRUD操作,以及如何组织和构建一个完整的RESTful API。实践过程中,你会遇到如视图的定义、序列化器的使用、URL路由的配置等多个关键点,这些都是构建高效API所...
基于QTable的Quasar Crud组件,使用Axios API来获取远程数据。 链接 安装 quasar ext add crud 卸载 quasar ext remove crud 演示版 未来... 资讯 使用Quasar默认类星体灭绝模板 您必须提供axios依赖关系 外部依赖 ...
crm-crud-basic REST和异步等待的CRM Crud
在本教程中,我们将深入探讨Spring MVC框架如何支持RESTful(Representational State Transfer)风格的CRUD(创建、读取、更新和删除)操作。REST是一种软件架构风格,广泛应用于Web服务设计,它强调资源的识别和...
具有DJANGO REST FRAMEWORK的简单CRUD API 是用于构建Web API的功能强大且灵活的工具包。 要求 Python 3.6 Django(2.1) Django REST框架 Django Rest身份验证 安装 pip install django pip install ...
标题“crud-angular:Crud Angular (Spring Rest + angular)”和描述“原油示例 Angular Crud(弹簧支架+角度)”提到了一个使用Angular前端框架与Spring后端框架构建的CRUD(创建、读取、更新、删除)应用。...
REST2SQL核心功能就是连接数据库即可提供REST和SQL的CRUD服务。在config.json里设置数据库连接字符串及服务端口等参数,REST服务提供POST、GET、PUT、DELETE4种请求,SQL服务可执行INSERT、SELECT、UPDATE、DELETE4...
"crud_api"项目是一个利用Python Django Rest Framework实现的简单CRUD REST API示例。通过这个项目,开发者可以学习到如何在Django中创建、读取、更新和删除数据,理解DRF中的序列化、视图、路由、认证和权限等关键...
PHP-CRUD-API 将REST API添加到MySQL / MariaDB,PostgreSQL,SQL Server或SQLite数据库的单文件PHP脚本。 注意:这是PHP中的参考实现。 相关项目: :单个文件PHP脚本,它是PHP-CRUD-API的身份验证提供程序 :将...
介绍这是一个基于Django(包括用于API CRUD操作的Django REST框架)和React构建的简单Todo应用程序。要求Python3 Pipenv入门将项目克隆到您的计算机上[git clone https://github.com/Jordanirabor/django-todo-react...
使用REST-API的简单Android CRUD应用程序。 这个简单的CRUD应用程序使用作为REST-API后端,建立在ExpressJS和MySQL数据库上。 安装 确保已在本地计算机上安装了Android Studio,NodeJ和MySQL服务器。 将复制到本地...
该项目不受支持如果你想为该项目做出贡献,请从该项目 fork 或给我发电子邮件,以便将你添加到 what-crud 组Vue 增删改查 基于 Vue.js 的 REST-ful CRUD 系统。Vue CRUD 既可以创建管理单个表的机制,也可以创建...
Angular-angular2-crud-rest.zip,示例角度(2.x和4.x)app:crud示例 routingangularcrudrest,Angularjs于2016年发布,是Angularjs的重写版。它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是...
**Dapper.SimpleCRUD** 是一个针对Dapper扩展的库,专为简化常见的数据库操作而设计,如创建、读取、更新和删除(CRUD)数据。Dapper本身是一个轻量级、高效的.NET ORM(对象关系映射)工具,而**Dapper.SimpleCRUD*...