REST entity id in PATCH request body - asp.net

Let's say I've got a FooEnity with an id of 35 exposed by a web service, and it is located at at /myhost/api/fooentity/35.
Now I want to implement a PATCH call to allow partial updates to FooEntity (so let's say 2 of the 25 available fields are passed up to be updated).
My question is, should the PATCH content (json/xml) include the id of 35? The address of the entity is specified by the URI, and id is not an updateable field, and if it was included it is an extra validation to make sure both ids match. All of this suggests No. Still, it feels weird not having it in there.
What is the appropriate way to do this?
(Note, question is language independent, but is implemented in the ASP.NET 4.0 Web API framework, if that influences anyone's answer).

That's a great question!
There are two ways you can handle that. You can either raise a validation error if the id in the body is different from the id in the URI. Or you can just ignore whatever id is in the request body. If you're patching by manually copying properties, you would just not copy the id property to ignore it. If you're using a helper class to patch the entity, you could apply the patch and then set the entity's id to be whatever came in on the URI just to make sure that it keeps the same id after the patch.
Whichever option you pick is really up to you. Sending back a 400 if the request body id doesn't match the entity id might be a little clearer for clients so they understand that the id won't be changed, but it also requires you to write more code to implement.

Related

Firestore Rules - get the size of request parameters

In firestore, request.resource.data.size() is equivalent to the size of the document in its final form. My question is, how can I get the parameters that are being sent from the client?
Meaning, if I the client tries to update the property name, then I want to check if the client has updated name and the size of the parameters he sent is just one parameter. I would've used hasExact() if it existed, but the problem is that I'm not sure if there's an object the specifies the requested parameters.
With the current request.resource.data.size(), I'm not sure how can do the following operations:
Deny writing updatedAt property (which is being updated as the server timestamp on each update) without an additional property.
Deny updating a property that is already equivalent to the requested value.
It's difficult to tell from your question exactly what you want to do. It doesn't sound like the size of the update is the only thing you need to be looking at. Without a more concrete example, I am just going to guess what you need
But you should know that request.resource.data is a Map type object. Click through to the linked API documentation to find out what you can do with a Map. That map will contain all the fields of a document that's being updated by the client. If you want the value of one of those fields, you can say request.resource.data.f where f is the name of the field. This should help you express your logic.
If you want the value of an existing field of a document, before it's written, use the map resource.data, which works the same way.

Where Merging two entities falls in Restful way

I have to do following:
Merge Source Entity to Target Entity. Both Source and Target Entity are of same type. So, end result would be both Source and Target would merge to one Target entity so that all the properties of Target will remain as it is, but if any of the property in Target is not there, it will be copied from Source.
In the end, source would be deleted.
My question is, in Restful way where should this fall - POST / PUT / DELETE and why?
Or, it will be multiple operations - PUT / POST followed by DELETE?
You can do it in one call. Assuming the unique id for the target remains the same in the new entity, just allow:
POST /entities/{targetEntityId}
{
"mergeFrom": "/entities/{sourceEntityId}
}
POST allows side effects, so you may choose to do the delete as part of this call. Alternately, you may choose to allow the client to determine whether or not the source gets deleted by requiring them to call DELETE /entities/{sourceEntityId} after the POST.
To use PUT, you'd need the client to do the merge and include all the values, which is presumably undesirable.

What's the RESTful way of attaching one resource to another?

this is one of the few moments I couldn't find the same question that I have at this place so I'm trying to describe my problem and hope to get some help an ideas!
Let's say...
I want to design a RESTful API for a domain model, that might have entities/resources like the following:
class Product
{
String id;
String name;
Price price;
Set<Tag> tags;
}
class Price
{
String id;
String currency;
float amount;
}
class Tag
{
String id;
String name;
}
The API might look like:
GET /products
GET /products/<product-id>
PUT /prices/<price-id>?currency=EUR&amount=12.34
PATCH /products/<product-id>?name=updateOnlyName
When it comes to updating references:
PATCH /products/<product-id>?price=<price-id>
PATCH /products/<product-id>?price=
may set the Products' Price-reference to another existing Price, or delete this reference.
But how can I add a new reference of an existing Tag to a Product?
If I wanted to store that reference in a relational database, I needed a relationship table 'products_tags' for that many-to-many-relationship, which brings us to a clear solution:
POST /product_tags [product: <product-id>, tag: <tag-id>]
But a document-based NoSQL database (like MongoDB) could store this as a one-to-many-relationship for each Product, so I don't need to model a 'new resource' that has to be created to save a relationship.
But
POST /products/<product-id>/tags/ [name: ...]
creates a new Tag (in a Product),
PUT /products/<product-id>/tags/<tag-id>?name=
creates a new Tag with <tag-id> or replaces an existing
Tag with the same id (in a Product),
PATCH /products/<product-id>?tags=<tag-id>
sets the Tag-list and doesn't add a new Tag, and
PATCH /products/<product-id>/tags/<tag-id>?name=...
sets a certain attribute of a Tag.
So I might want to say something link this:
ATTACH /products/<product-id>?tags=<tag-id>
ATTACH /products/<product-id>/tags?tag=<tag-id>
So the point is:
I don't want to create a new resource,
I don't want to set the attribute of a resource, but
I want to ADD a resource to another resources attribute, which is a set. ^^
Since everything is about resources, one could say:
I want to ATTACH a resource to another.
My question: Which Method is the right one and how should the URL look like?
Your REST is an application state driver, not aimed to be reflection of your entity relationships.
As such, there's no 'if this was the case in the db' in REST. That said, you have pretty good URIs.
You talk about IDs. What is a tag? Isn't a tag a simple string? Why does it have an id? Why isn't its id its namestring?
Why not have PUT /products/<product-id>/tags/tag_name=?
PUT is idempotent, so you are basically asserting the existance of a tag for the product referred to by product-id. If you send this request multiple times, you'd get 201 Created the first time and 200 OK the next time.
If you are building a simple system with a single concurrent user running on a single web server with no concurrency in requests, you may stop reading now
If someone in between goes and deletes that tag, your next put request would re-create the tag. Is this what you want?
With optimistic concurrency control, you would pass along the ETag a of the document everytime, and return 409 Conflict if you have a newer version b on the server and the diff, a..b cannot be reconciled. In the case of tags, you are just using PUT and DELETE verbs; so you wouldn't have to diff/look at reconciliation.
If you are building a moderately advanced concurrent system, with first-writer-wins semantics, running on a single sever, you can stop reading now
That said, I don't think you have considered your transactional boundaries. What are you modifying? A resource? No, you are modifying value objects of the product resource; its tags. So then, according to your model of resources, you should be using PATCH. Do you care about concurrency? Well, then you have much more to think about with regards to PATCH:
How do you represent the diff of a hierarchial JSON object?
How do you know what PATCH requests that conflict in a semantic way - i.e. we may not care about DELETEs on Tags, but two other properties might interact semantically.
The RFC for HTTP PATCH says this:
With PATCH, however, the enclosed entity contains a set of
instructions describing how a resource currently residing on the
origin server should be modified to produce a new version. The PATCH
method affects the resource identified by the Request-URI, and it also
MAY have side effects on other resources; i.e., new resources may be
created, or existing ones modified, by the application of a PATCH.
PATCH is neither safe nor idempotent as defined by [RFC2616], Section
9.1.
I'm probably going to stop putting strange ideas in your head now. Comment if you want me to continue down this path a bit longer ;). Suffice to say that there are many more considerations that can be done.

Authorize request in ASP.NET Web API based on specific user

I followed this tutorial http://www.tugberkugurlu.com/archive/api-key-authorization-through-query-string-in-asp-net-web-api-authorizationfilterattribute
to create custom Authorization filter.
I have CarController with my custom Authorize Attribute:
[ApiKeyAuth("apiKey", typeof(ApiKeyAuthorizer))]
I send two parameters in the url .. host/Car/4?username=xxx&pass=xxx
It works basically fine, however I want to allow only car owners to see information about their cars.
E.g. user ABC can see only host/Car/5 and user DEF can see host/Car/6 and host/Car/10
how can I solve this scenario?
How can I access the id of the car used in query (host/Car/ID) in my ApiKeyAuthorizer.
Greetings
If you look at his code, https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/samples and https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/TugberkUg.Web.Http, I think you'll find that he's pulling the data directly from the query string. It should simply be a matter of extending that method to pull in the id parameter. You might also want to look at the RequestContentKeyValueModel on the HttpActionContext parameter passed into the OnAuthorization method. The documentation is sketchy and I haven't played with it yet, but that seems like a likely candidate to me. However, the route data is available indirectly through the HttpRequestMessage via an extension method, specifically:
message.GetRouteData();

Looking for a good technique for storing email templates

I am building a site in which we are making moderate use of email templates. As in, HTML templates which we pass tokens into like {UserName}, {Email}, {NameFirst}, etc.
I am struggling with where to store these, as far as best practice goes. I'll first show the approach I took, and I'd be really excited to hear some expert perspective as a far as alternate approaches.
I created HTML templates in a folder called /Templates/.
I call a static method in my service layer, which takes in the following arguments:
UserName
UserID
Email
TemplatePath ("~/Templates")
Email Subject
Within the service layer I have my static method SendUserEmail() which makes use of a Template class - which takes a path, loads it as a string, and has a AddToken() Method.
Within my static SendUserEmail(), I build the token list off of the method signature, and send the email.
This makes for a quite long method call in my actual usage, especially since I am calling from the web.config the "TemplatePath", and "Email Subject". I could create a utility that has a shorter method call than the ConfigurationManager.AppSettings, but my concern is more that I don't usually see method signatures this long and I feel like it's because I'm doing something wrong.
This technique works great for the emails I have now, which at the most are using the first 3 tokens. However in the future I will have more tokens to pass in, and I'm just wondering what approach to take.
Do I create methods specific to the email needing to be sent? ie. SendNewUserRegistration(), SendMarketingMaterial(), and each has a different signature for the parameters?
I am using ASP.NET Membership, which contains probably the extend of all the fields I'll ever need. There are three main objects, aspnet_User, aspnet_Mebership and aspnet_profile. If it was all contained in one object, I would have just passed that in. Is there performance concerns with passing in all 3, to get all the fields I need? That is versus just passing in aspnet_User.UserID, aspnet_User.Email, etc?
I could see passing in a dictionary with the token entries, but I'm just wondering if that is too much to ask the calling page?
Is there a way to stick these in a config file of it's own called Templates.config, which has tags like -
<Templates>
<EmailTemplate Name="New User Registration">
<Tokens>
<UserName>
<UserID>
<Email>
</Tokens>
<Message Subject="Hi welcome...">
Hi {UserName}...
</Message>
</EmailTemplate>
</Templates>
I guess the main reason I'm asking, is because I'm having a hard time determining where the responsibility should be as far as determining what template to use, and how to pass in parameters. Is it OK if the calling page has to build the dictionary of TokenName, TokenValue? Or should the method take each in as a defined parameter? This looks out of place in the web.config, because I have 2 entries for and , and it feels like it should look more nested.
Thank you. Any techniques or suggestions of an objective approach I can use to ask whether my approach is OK.
First of all I would like to suggest you to use NVelocity as a template engine. As for main problem I think you can create an abstract class MailMessage and derive each one for every needed message (with unique template). So you will use this like following:
MailMessage message = new UserRegistrationMessage(tokens);
//some code that sends this message
Going this way you force each concrete XXXMessage class to be responsible for storing a template and filling it with the given tokens. How to deal with tokens? The simpliest way is to create a dictionary before passing it to the message, so each concrete message class will know how to deal with passed dictionary and what tokens it should contain, but you also need to remember what tokens it should contain. Another way (I like it more) is to create a general abstract type TokenSet and a derived one for every needed unique set of tokens. For example you can create a UserMessageTokenSet : TokenSet and several properties in it:
UserNameToken
SomeUserProfileDataToken
etc. So using this way you will always know, what data you should set for each token set and
UserRegistrationMessage will know what to take from this tokenSet.
There are a lot of ways to go. If you will describe you task better I think I will try suggest you something more concrete. But general idea is listed above. Hope it helps =)

Resources