Comments (5)
afaik, the SuppressModelStateInvalidFilter
setting doesn't prevent the validation from running, it only stops the MVC pipeline from returning a BadRequest response when the Model is invalid.
from northwindtraders.
You have one more option:
command.id = id; // enforced consistency
await Mediator.Send(command);
return NoContent();
from northwindtraders.
This is also not that perfect -- in swagger (and more importantly, in auto-generated clients) id will appear both in route and body.
And, what's even worse, fluentvalidation will get broken because it runs before controller is actually called.
from northwindtraders.
A good question. We need the Id in the command, since the command needs to contain all information nececessary to update a customer. We also need the Id in the route, since we are building (at least trying to build) restful APIs.
I think the best approach is to handle this at the Web API level, since it is an API concern. That being the case, my recommendation is as follows:
if (id != command.Id)
{
return BadRequest();
}
At this stage, I don't think more effort is required. If this approach ends up being too painful, I'll change it later.
And, what's even worse, fluentvalidation will get broken because it runs before controller is actually called.
Just on the above point. In this case, fluent validation only runs on the commands and queries, not the controller actions. This is a result of the following within Startup.cs:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
And the following validation behaviour; https://github.com/JasonGT/NorthwindTraders/blob/master/Northwind.Application/Infrastructure/RequestValidationBehavior.cs.
Hope this helps.
from northwindtraders.
A good question. We need the Id in the command, since the command needs to contain all information nececessary to update a customer. We also need the Id in the route, since we are building (at least trying to build) restful APIs.
I think it is not mandatory to include server generated (Id, TimeStapmps (creation date), Unique Sequential numbers) info in a PUT resource representation, if like you say at least trying to build restful APIs.
The reason is that resource reprepresntation from the GET request may be different from the resource representation you use in PUT request, but it does not meant that the representation is not complete/full, but the resource is still same. e.g. up to you to decide that concrete representation is complete/describes the resource completely. Its obvious and mandatory to include in the put representation all fields that user may/can change but not for the server side generated stuff.
From the RFC 7231 4.3.4 PUT:
If the target resource does not have a current representation and the
PUT successfully creates one, then the origin server MUST inform the
user agent by sending a 201 (Created) response.
It (HTTP) does not define how
resource state is "stored", nor how such storage might change as a
result of a change in resource state, nor how the origin server
translates resource state into representations. Generally speaking,
all implementation details behind the resource interface are
intentionally hidden by the server.
The RFC 7231 itself does not says that it is requred to create a new resource on a put, only to respond correctly if server actually creates a new one. Also the Id field is not the resource identifier in a REST. Identificator for the client is a resource url itself, location - the whole url. The Id field in this case is more like implementation details that your backend API is using internally to track entites and recognize them. But if your client using ID field for url construction (hacking urls) thats not good and should not affect your API design. This leads to a hypermedia question, but that not the case of this topic.
An origin server SHOULD verify that the PUT representation is
consistent with any constraints the server has for the target
resource that cannot or will not be changed by the PUT. This is
particularly important when the origin server uses internal
configuration information related to the URI in order to set the
values for representation metadata on GET responses.
The Rest CookBook says:
Use PUT to create new resources only when the client can control part of the URI. For
instance, a storage server may allocate a root URI for each client and let clients create
new resources using that root URI as a root directory on a filesystem. Otherwise,
use POST.
When you support PUT to create new resources, clients must be able to assign URIs for
resources.
So i assume if API is not supporting creation of resources via PUT(only replacement the contents of an existing resource, not location change) because Id is generated on server side by ORM (EF) and client cant decide it by himself, removing the Id field from the PUT representation is ok and it will be still complete (representation is still complete).
Another good example of different representations provided in Rest in Practice:
In example there used a PUT reqeust to to change resource state with one representation while having a
respone 200 OK with other reprsentation that contains a status field, that cannot be desided by client.
There’s no order ID embedded
in the payload, since it would be superfluous. Following this DRY (Don’t Repeat
Yourself) pattern, we avoid potential inconsistencies between the domain model
and the resources the service exposes, and keep the URI as the authoritative
identifier, as it should be.
**PUT /order/1234 HTTP/1.1**
Host: restbucks.com
Content-Type: application/xml
Content-Length: 246
<order xmlns=″http://schemas.restbucks.com/order″>
<location>takeAway</location>
<items>
<item>
<milk>skim</milk>
<name>cappuccino</name>
<quantity>1</quantity>
<size>large</size>
</item>
</items>
</order>
HTTP/1.1 200 OK
Content-Length: 275
Content-Type: application/xml
Date: Sun, 30 Nov 2008 21:47:34 GMT
<order xmlns=″http://schemas.restbucks.com/order″>
<location>takeAway</location>
<items>
<item>
<milk>skim</milk>
<name>cappuccino</name>
<quantity>1</quantity>
<size>large</size>
</item>
</items>
**<status>preparing</status>**
</order>
There are a couple of question on a stack about it:
https://stackoverflow.com/questions/19821221/rest-api-design-of-a-resource-whose-properties-are-not-editable-by-the-client
https://stackoverflow.com/questions/36498982/same-representation-for-get-and-put
from northwindtraders.
Related Issues (20)
- Consistent naming for behaviors HOT 1
- Why is CQRS put in Application and not in WebUI? HOT 2
- Do non-entities core models belong to the domain? HOT 2
- Use ProblemDetails/ValidationProblemDetails etc for exception middleware
- Use ProblemDetails/ValidationProblemDetails etc for exception middleware? HOT 1
- How can we write unit test cases for controllers extending base controller as we are not using constructor injection. any leads will be appreciated. HOT 1
- What's the point of having the IDateTime interface? HOT 2
- FromSqlRaw won't work in Application HOT 2
- ValueObject.Equals bug when objects have a different number of values HOT 1
- [Question] Should JWT/RefreshToken creation be on infrastructure? HOT 1
- [Discussion] Clean Architecture - is it really? HOT 4
- Why does it not look like shown in the XAML ControlsGallery App - DataGrid HOT 4
- Dealing with duplication HOT 6
- Application layer access to DbContext? HOT 2
- A better way to do upsert HOT 1
- Suggestion: Request with record type
- something similar HOT 1
- IDbContext and repository pattern HOT 1
- How to call stored procedure for CURD operation? HOT 1
- This repo is pretty old and the projects don't event load in VS 2022 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from northwindtraders.