I feel a bit sad to see that after more than 10 years there is no answer really stating how such a thing as requested in the OP could be designed in a REST architecture, hence I feel the need to do this now.
First things first, what is REST?! The acronym REST or ReST stands for "Representational State Transfer" and defines the exchange of a resource's state in a certain representation format. The representation format is tide to the negotiated media type. In the case of application/html
the representation format may be a stream of HTML formatted text content that is rendered in the browser, probably after applying some stylesheet formatting to position certain elements at certain locations.
REST is in principle a generalization of the browsable Web we all know, though targets all kinds of applications and not only browsers. Therefore, by design, the same concepts that apply to the Web also apply to a REST architecture. A question like how to achieve something in a "RESTful" way resolves around answering the question how to achieve something on a Web page and then apply the same concepts onto the application layer.
A Web based calculator may usually start off with some "page" that allows you to input some values to calculate before sending the entered data to the server. In HTML this is usually achieved via HTML <form>
elements that teaches a client on the available parameters to set, the target location to send the request to as well as the representation format to apply upon sending the input data. This can i.e. look like this:
<html>
<head>
...
</head>
<body>
<form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
<label for="firstNumber">First number:</label>
<input type="number" id="firstNumber" name="firstNumber"/>
<label for="secondNumber">Second number:</label>
<input type="number" id="secondNumber" name="secondNumber"/>
<input type="submit" value="Add numbers"/>
</form>
</body>
</html>
The sample above i.e. states that there are two input fields that can be filled out either by the user or by some other automata, and that upon invoking the submit input element the browser takes care of formatting the input data into a application/x-www-form-urlencoded
representation format that is sent to the mentioned target location via the specified HTTP request method, POST
in this case. If we enter 1
into the firstNumber
input field and 2
into the secondNumber
input field, the browser will generate a representation of firstNumber=1&secondNumber=2
and send this as the body payload of the actual request to the target resource.
The raw HTTP request issued to the server therefore may look like this:
POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html
firstNumber=1&secondNumber=2
The server may perform the calculation and respond with a further HTML page that contains the result of the calculation, as the request indicated that the client understands this format.
As Breton pointed already out there is no such thing as a "RESTful" URL or URI. A URI/URL is its own kind of thing and should not convey any meaning to a client/user. In the calculator sample above a user simply isn't interested where to send the data to it is just interested in that upon triggering the submit input field the request is sent. All the required information needed to perform the task should already be given by the server.
A browser also might not be aware of that the request is actually feeding a calculator with some input parameters, it could as well be some kind of an order form that returns just the next form representation to continue the ordering process or some totally different kind of resource. It simply performs what the HTML spec demands in such a case and it couldn't care less what the server is actually doing. This concept enables a browser to use the same representation format to do all kind of things such as ordering some stuff from your preferred online shop, chatting with your best friends, signing into an online account and so on.
The affordance of certain elements, such in the submit input field case that is usually rendered as button, defines what you should to with it. In the case of a button or a link it basically tells you to click it. Other elements may convey different affordances. Such an affordance can also be expressed via link-relations as i.e. with preload
annotated links that basically tell a client that it can already load the content of the linked resource in the background as the user will most likely grab this content next. Such link relations should of course be standardized or follow the extension mechanism for relation types as defined by Web linking.
These are the fundamental concept that are used on the Web and that should also be used in a REST architecture. According to "Uncle Bob" Robert C. Martin an architecture is about intent and the intention behind the REST architecture is the decoupling of clients from servers to allow servers to evolve freely in future without having to fear them breaking clients. This unfortunately requires a lot of discipline as it is so easy to introduce coupling or to add quick-fix solutions to get the job done and move on. As Jim Webber pointed out in a REST architecture you, as a service provider, should attempt to design an domain application protocol similar to a text based computer game of the 70s that clients will follow through until they reached the end of a process.
What plenty of so-called "REST" APIs unfortunately do in reality is everything but that. You see the exchange of mostly JSON based data that is specified in an API specific external documentation that is usually hard to dynamically integrate on the fly. The format how a request needs to look like are also hardcoded into the external documentation which lead to plenty of implementation interpreting URIs to return predefined typs instead of using some common representation format that is negotiated upfront. This prevents servers from changing as clients now expect to receive a certain data format (note not representation format!) for predefined URIs. This custom data format exchange furthermore prevents clients from interacting with other APIs as the "data format" is usually tide to a specific API. We know this concept from the past from RPC technologies such as Corba, RMI or SOAP which we condemn as somehow evil, even though Peppol moved to it again by replacing AS2 with AS4 as default transfer protocol as of recently.
In regards to the actual question asked, sending data as csv file is nothing different than using application/x-www-form-urlencoded
representation or similar stuff. Jim Webber made it clear that after all HTTP is just a transport protocol whose application domain is the transfer of documents over the Web. Client and server should at least both support text/csv
as defined in RFC 7111. This CSV file could be generated as a consequence of processing a media type that defines form elements, a target element or attribute to send the request to as well as the HTTP method to perform the upload of the configuration.
There are a couple of media types that support forms such as HTML, HAL Forms, halform, ion or Hydra. I am currently, though, not aware of a media type that automatically can encode the input data into text/csv
directly hence one might need to be defined and registered with IANA's media type registry.
The upload and download of the complete parameter set shouldn't be an issue I guess. As mentioned before, the target URI is not of relevance as a client will just use the URI to retrieve new content to process. Filtering by business date should also not be to difficult. Here the server should however the client with all the possibilities the client simply can chose from. In recent years GraphQL and RestQL evolved which introduce an SQL like language that can be targeted at a certain endpoint to get a filtered response. However, in a true REST sense this violates the idea behind REST as a) GraphQL i.e. only uses a single endpoint which somehow prevents optimal usage of caching and b) requires the knowledge of available fields upfrong, which may lead to introducing a coupling of clients to the base data model of the resource.
Activating or deactivating certain configuration parameters is simply a matter of triggering the hypermedia controls that provide this affordance. In HTML forms this could be a simple checkbox or a multi-line selection in a list or that kind. Depending on the form and what method it defines it could then potentially send the whole configuration via PUT
or be smart about the changes done and only perform a partial update via PATCH
. The latter one requires basically a calculaton of the change representation to the one updated and feed the server with the required steps to tranform the current representation into the desired one. According to the PATH specification this has to be done within a transaction so that either all or none of the steps are applied.
HTTP allows and encourages a server to validate a received request upfront before applying the changes. For PUT the spec states:
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. When a PUT
representation is inconsistent with the target resource, the origin
server SHOULD either make them consistent, by transforming the
representation or changing the resource configuration, or respond
with an appropriate error message containing sufficient information
to explain why the representation is unsuitable. The 409 (Conflict)
or 415 (Unsupported Media Type) status codes are suggested, with the
latter being specific to constraints on Content-Type values.
For example, if the target resource is configured to always have a
Content-Type of "text/html" and the representation being PUT has a
Content-Type of "image/jpeg", the origin server ought to do one of:
a. reconfigure the target resource to reflect the new media type;
b. transform the PUT representation to a format consistent with that
of the resource before saving it as the new resource state; or,
c. reject the request with a 415 (Unsupported Media Type) response
indicating that the target resource is limited to "text/html",
perhaps including a link to a different resource that would be a
suitable target for the new representation.
HTTP does not define exactly how a PUT method affects the state of an
origin server beyond what can be expressed by the intent of the user
agent request and the semantics of the origin server response. ...
To sum this post up, you should either use an existing media type that allows you to teach a client about the required or supported input parameters, the target location to send the request to, the operation to use as well as the media-type the request has to be formatted in, or define your own one that you register with IANA. The latter might be necessary if you want to convert the input to text/csv
and then upload the CSV representation to the server. The validation should occur before the changes are applied to the resource. The actual URI should not be of relevance to clients other than to determine where to send the request to and as such can be freely chosen by you, the service implementor. By following these steps you pretty much gain the freedom to change your server side at any time and clients will not break as a consequence if they support the used media-types.