Consider I want to develop a RESTfull WebApi for a Book Store. I'll have an Api to get a book info like: books/1.
I want to create a log whenever someone gets a book info. So, later I can produce a report of which book is seen more through the Api.
As in this scenario I'm getting some information it seems more appropriate to use GET. But as it changes some data, it could be a SET request.
Question: Does some changes like Logging effect on idempotent behavior of an action?
The general pattern is that a GET of a resource should not modify the resource in such a way that a subsequent GET of the same resource gets a different result.
Side-effects such as logging are not part of the data model, so are not generally considered to be related to whether the action is idempotent or not.
Related
My understanding of Asp.net restful web service is that for each resource , there are corresponding get,post,delete,put verbs.
But what if I have to submit a request to server that needs to operate on more than one resource?
e.g., for a submit form, I have to ask the server to create an order and in the same request a new order history.
For me , I define an order and an order history as two different resources.
And if we follow the ASP.NET MVC Web api restful web service, we will create two controllers, one named OrderController, and the other one OrderHistoryController.
And each controller has the “get,post,delete,put” verbs.
The question is how can we make sure that the creation of an order and the creation of an order history are in one transaction ?
How and when to call the OrderHistoryController’s post method to create an OrderHistory after the Order’s creation ?
I currently am not sure how to achieve this with OrderHistory being a resource.
Thanks for answering.
For starters, you probably won't want PUT and DELETE operations in OrderHistories. Being able to change/delete history generally isn't a good idea. (You probably don't even want a POST operation on that resource. The server-side logic should create its own OrderHistory objects any time an Order is created/modified/deleted.)
Aside from that...
You don't maintain a transaction (or, more generally, a unit of work) across multiple HTTP requests. Each request would be an isolated and otherwise atomic unit of work in and of itself.
So essentially what you're looking to do here is issue a POST to the Orders resource to create an Order object. The server-side logic in this operation would, within that same unit of work, also create any necessary corresponding records in OrderHistories.
Depending on how you select from these resources, you'd return information from that POST operation needed to query them. For example, it's unlikely that you'd ever want to query an OrderHistory by its own identifier right away, you'd probably query by the Order ID. So when creating an Order object, the returned server-generated ID for that object could be used by the client to query the OrderHistories if they want.
Ultimately, it sounds like the confusion here is from the mistaken notion that a RESTful service is basically a pass-through set of operations to database tables. It isn't. The consuming client shouldn't be responsible for maintaining transactional integrity or relational integrity. The server-side operations maintain that.
I'm very new to Application Insights, and I'm thinking of using it for a set of services I plan on implementing with asp.net webapi. I was able to get the basic telemetry up and running very easily (right-clicking on a project on VS, Add Application Insights), but then I hit a block. I plan to have a correlation id set in the request headers for calls to downstream services, and I would like to tag all the telemetry related to one outside call with the same correlation id.
So far I've found that there is a way to configure a TelemetryInitializer, but if I understood correctly, this is run before I get to access the request, meaning I can't check if there is a correlation id that I should attach.
So I guess there might be 2 ways to solve this: 1) if I can somehow actually get access to the request headers before the initializer, that would obviously solver the problem, or 2) somehow get a hold of the TelemetryClient instance that is used to report the automatically generated telemetry.
Perhaps the last resort would be to turn off all of the automatic stuff and do all of it manually, when I could of course control what properties are set on the TelemetryClient. But this would be quite a lot more work, so I'd prefer to find some other solution.
You were rights saying that you should use TelemetryInitializer. All TelemetryInitializers are called when Track method is called on any telemetry item. Autogenerated request telemetry is "tracked" on request OnEnd, you should have all your custom headers available for you at that time.
Please also have a look at OperationId - this is part of the standard context managed by App Inisghts and is used exactly for the purpose of correlating requests with downstream execution. This is created and passed automatically, including traces (if you use trackTrace).
Moreover, we have built-in support in our UX for easily seeing all telemetry for a particular operation - it can be found in "Search->Details-->Related Items-->All telemetry for this operation"
I want to implement a query on my web page that gets results from another web service and displays them to the user. For this I ofcourse send the request as GET method from the web page. Server side, I process the request, get results from that web service and return them back to user.
However, I also want to save the results for future refernce. Something like history of queries. For this I will store the results in a database.
Now, the question is since I am upating my database everytime a query is made, should I be using POST method on the web page or GET would do? Does HTTP explicitly say anything for this scenario?
HTTP itself doesn't say you have to use POST -- the technology will work just fine if you're sending your data on queryparams.
But current convention says that you should use POST, specifically when using API services under a RESTful model. If you are passing data (even on the query params) that is creating a new record, it should use the POST verb. Updating it should use PUT.
It's going to get down to what your audience expects. If it's just an internal resource, go for it with GET. If you expect to open this up as a public service, use POST.
Lets say I am building a web service that is returning a random number?
Real world example: http://www.random.org/integers/?num=10&min=1&max=6&col=1&base=10&format=plain&rnd=new
random.org does this via GET method, which is not RESTful I think. Specs are saying that GET method should be idempotent.
What method would you suggest and what would your URL be?
There is no problem here. Being idempotent has nothing to do with returning the same thing all the time.
I am using The Policy Injection Application Block to log methods that are called in my ASP.NET application. I would like these log entries to include information like the current user identity, whether the user is authenticated and so forth. All of this information is provided by the ManagedSecurityContextInformationProvider, but I can't figure out how to get the PIAB to use that provider and how to get that information into my log file.
I may be missing something obvious, but I can't quite figure out what it is.
Sorry to say, it looks like there is no way to get the ManagedSecurityContextInformationProvider information into method call logs. That information is usually logged in extended properties but the LogCallHandler.GetLogEntry method dumps out all of the method parameters and assigns them to the TraceLogEntry ExtendedProperties.
It seems to me that you could either modify the block to add that information or (even better) create your own Custom Call Handler based on LogCallHandler that adds the information that you require. Either option is not that much work.