Environment: REST API (Spring MVC) + SPA (AngularJS)
Let's assume I have two resources available via the following URIs, respectively.
/resource/1 -> Resource #1
/resource/2 -> Resource #2
My application business logic allows me to merge one resource into another. Let's say I merge Resource #1 into Resource #2. After doing so, any future requests to Resource #1 should return Resource #2. The same would apply to any child resources, for instance, if I have
/resource/1/child-resource -> Child Resource #1
/resource/2/child-resource -> Child Resource #2
then any requests to Child Resource #1 should return Child Resource #2 following the merge. This is not only for representations of this information in the client. For all intents and purposes, Resource #1 is gone and any references to it in the application should return Resource #2.
If this were a typical HTTP request, sending a 301 redirect response the location header reflecting the new URI to the resource which would force the client (browser) to redirect to that URI is clear. What I am not certain about is how to do this properly when using an SPA and AJAX requests, namely
whether the controller should internally resolve the proper ID for the requested resource and return that resource in one go, or
should it return a 301 response as described above and the frontend code would have to deal with handling the redirect (which should not reload the page).
What is the proper way to respond to such requests given this business logic?
Related
I am learning Django Rest Framework and one of the things I have noticed is that Viewsets provide actions such as .list, .post instead of method handlers such as .get, .post which in turn are provided by Views. The documentation says that actions are more flexible than method handlers but I can't seem to find any reason for this. Could you please share some information on why does Viewsets use actions and not the method handlers?
request handlers like .get() and .post() are based on http request methods, while actions like .create() or .list() are from a functionality point of view. Suppose you have a view class that can return a single user's info by user id or return all users in sorted order. These two requests are all GET requests from the client side, but with different parameters and purposes. If you just want to use .get() handler in this case you will need to define two view functions and register the two urls in url config. Or you can use ViewSet class or generic view with mixins that has action functions .list() and .retrieve() to handle these requests, then using router class to set the url configs that follows the REST url standards.
GET and POST are the only HTTP methods to use when dealing with forms.
Django’s login form is returned using the POST method, in which the browser bundles up the form data, encodes it for transmission, sends it to the server, and then receives back its response.
GET, by contrast, bundles the submitted data into a string, and uses this to compose a URL. The URL contains the address where the data must be sent, as well as the data keys and values. You can see this in action if you do a search in the Django documentation, which will produce a URL of the form https://docs.djangoproject.com/search/?q=forms&release=1.
GET and POST are typically used for different purposes.
Any request that could be used to change the state of the system - for example, a request that makes changes in the database - should use POST. GET should be used only for requests that do not affect the state of the system.
GET would also be unsuitable for a password form, because the password would appear in the URL, and thus, also in browser history and server logs, all in plain text. Neither would it be suitable for large quantities of data, or for binary data, such as an image. A Web application that uses GET requests for admin forms is a security risk: it can be easy for an attacker to mimic a form’s request to gain access to sensitive parts of the system. POST, coupled with other protections like Django’s CSRF protection offers more control over access.
On the other hand, GET is suitable for things like a web search form, because the URLs that represent a GET request can easily be bookmarked, shared, or resubmitted.
I have a general REST API (developed using Spring MVC) that takes a list of API requests as its request body.
Each API request in the list has its own URL and request body.
In the implementation of this general REST API, I need to call the corresponding Spring controller method (in the same app) for each of these individual API requests (with their appropriate URL and request body).
(I will then merge all those individual API responses and return it in one big response from the general REST API).
I've been searching around, but I'm unclear how to programmatically call Spring to execute each individual API request. I would ideally like to get back the ResponseEntity from each call instead of the actual JSON response.
(More information:
On the same app server as the general API, I need to translate the URL and JSON request body for each individual API into the arguments to the controller method. I also need to take the URL and have Spring determine which controller method to invoke itself.)
Any help would be greatly appreciated.
Thanks,
Matt
Answer depend on whether the individual URLs that you are planning to invoke is with in the same server (Accessible without using network call) or not
If it is with in the same app server, spawn multiple threads and invoke the individual methods and join the response together and send it back
If it is not within the same app server, there are many Async Restclients are there besides spring's own webclient/restTemplate etc
Currently all the Fulfilment requests originating from api.ai are, POST requests to the base url configured in api.ai Fulfilment section. But to be able to have proper routing (microservice style) set-up on the server side it would be more worthwhile to append the action in the POST URL.
For a substantially large project, there can be hundreds of fulfilment actions and managing all of them in single monolithic project is cumbersome. If the action comes in the URL, then we can configure and organise the actions into multiple cloudfunctions in case of firebase hosting / server side microservices.
Edit:
As answered by matthewayne, I can use my own proxy set-up to route the requests to achieve the goal. But I don't want to introduce any additional delay into the request processing. Because I am expecting huge number of webhooks being fired. This would be a very easy implementation for Google api.ai team to incorporate that allows for a greater flexibility! Hence expecting an answer from google team!
Currently this isn't possible with API.AI's webhook design. I'd recommend setting up a proxy service that unpacks the webhook requests from API.AI, inspects the action and sends the proper request to the proper microservice endpoint and then forwards the response back to API.AI once the microservice has returned its result:
I have a server in which the client can register itself as a device (like a mobile device). For the registration, the device must be associated with another resource (say an user) which is already registered on the server. To do that, the client sends a Http Post request to the server, with two params, its own ID and the associated resource ID.
I need to choose an Http Status code to return when the client ask the server to do some procedure and one of the resources indicated in the parameters are not found.
I suggested 404, but my professor said that 404 is used the resource associated to the URI is not found, not when you submit a well-formed request with bad parameters.
What is the most suitable http status and why would you choose?
In my opinion, it fits to:
400 - Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
OR
403 - Forbidden
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
Ref: fc2616
I would use 403 'Forbidden' - meaning, you are forbidden from accessing the page with the request you have sent
Is it possible to access the current request information (HttpRequestMessage) outside of the context of a controller?
I would like to setup a tenant strategy (ITenantIdentificationStrategy) that involves the incoming request headers. In self hosted mode HttpContext.Current is not an option and I haven't found any other solutions.
It sounds like a HttpMessageHandler is what you are looking for. MessageHandlers allow you to perform some kind of processing on every request and provides full access to the request and response message.