I understand how to use REST for doing general entity interactions - using urls names to map to entities and the HTTP verbs to map to actions on those entities. But what is the generally accepted way of looking at "actions" more like RPC?
For example, let's say I want to send a command for the device to reset? There's no real "entity" here or do I do something like POST to http://mydevice/device/reset?
/device/reset or /system/reset are ok.
The REST "design pattern" does encourage you to NOT use any verbs.. You could do:
POST http://mydevice/system/state
<stateType>RESET</stateType>
Related information:
How to create REST URL’s without verbs?
Threads tagged with restful-url
I don't think that's the case to use POST. The "RESET action" is a idempotent action (if you call it n times you will always get the same result), so IMHO you should use a PUT call instead POST (as POST is not idempotent).
Also, as you are Putting a resource, you can use
PUT http://system
<device>
<status>RESET</status>
</device>
or
PUT http://system/status/reset
But I think the first one is "more restful", since you are putting a resource, while the second one you just use the URL.
I usually name the entity "system" or something like that. So you do "/system/reset". You've chosen device so that works too.
But yea, I usually consider these types of actions to be updates, which would use the POST method. So I think you are right to POST to /device/reset
Related
I have $dinetype variable obtained from the user.
But I would like to give response based on what value has been set in $dinetype variable. In addition to giving responses, I also need to set relevant context. How do I do this in DialogFlow?
if($Dinetype=='dineout')
ask ('which restaurant would you like to go to?')
set_context ('awaiting-restaurant')
if($Dinetype=='takeaway')
ask ('When would you like to take away?')
set_context ('awaiting-takeaway-time')
Is it programmable at all? Or is it possible to achieve something equivalent to the above in the UI?
Edit: A much easier way has been added to handle this issue directly in Dialogflow
(Updated Solution) Follow-up Intents:
After creating an intent, you can add follow-up intents now.
Intents -> Create Intent >
[Response=Prompt For Conditional Response]
Intents -> Add Follow-up Intent -> Custom/Yes/No
Then set the training praise to a matching entity you want to conditionally respond to
OLD HACKY SOLUTION:
Late reply, but maybe someone will find this useful.
If the conditional response only needs to reference a single parameter
value, then I figured out what you can do is utilize the Entity's
"Reference Value" as the response you want to give for a particular
set of Synonyms.
So you'd have an entity that looked like this:
Then, setup your intent like this, with a response of $Dinetype:
Then the end result will look like this:
And you can make whatever follow-up intent you need from there.
Down-side is Dinetype won't be as reusable. But I still think it
beats writing a fulfillment webhook every time you need a simple
conditional response.
You can't do this in the Response section directly. The Response section is meant for fairly simple responses that don't require significant logic to process. Although you can use parameters in the response, you can't give a different response based on the value of the parameter. So you can set a response to something like
I think $Dinetype is great food.
but not
{{#if $Dinetype == "Thai"}}I think Thai food is too hot{{/if}}
or anything like that
However, you can add code that sends conditional responses and contexts by implementing a Fulfillment webhook. Although you can't do this for each Intent as part of the Intent editor screen, the Fulfillment screen includes a built-in code editor.
I found a solution to my similar problem using composite entities, which may or may not be overkill for your agent. The value assigned to a parameter associated with the (composite) entity will contain a JSON structure, if a synonym in that entity was matched.
Using the "Dot" notation, you can assign the matched sub-entity's property (similar to the reference value of a normal entity) to another parameter in the Actions and Parameters section. You can have one parameter for each sub-entity and hence, you can evaluate these parameters in your response section to select each response variants:
$Parameter_A ResponseA
$Parameter_B ResonseB
....
etc.
Clunky but works. Just have to be careful to reference the property exactly as it is defined in the composite entity.
I'm designing a REST API where, amongst others, there are two objects.
Journey
Report
For each Journey there are many Reports enroute, and each Report has exactly one associated Journey.
A user might create a Journey using the API as follows...
POST /journey/
Then retrieve the details...
GET /journey/1226/
The first question is, if a user wanted to post an Report to their Journey, which is the 'correct' URL structure that the API should impose? This seems intuitive to me...
POST /journey/1226/report/
...or is this the case...
POST /report/
...whereby in the latter, the Journey ID is passed in the request body somewhere?
The second question is, how might one go about implementing the first case in a tool such as the Django REST framework?
Thanks!
The URL/URI structure is almost completely irrelevant. It is nice to be able to read it, or easily change or even guess it, but that is it. There is no "requirement" official or unwritten how they should look like.
The point is however, that you supply the URIs to your clients in your responses. Each GET will get you a representation that contains links to the next "states" that your client can reach. This means the server has full control over URI structure, the client usually has to only know the "start" or "homepage" URI, and that's it.
Here is an article which discusses this question, has some good points: http://www.ben-morris.com/hackable-uris-may-look-nice-but-they-dont-have-much-to-do-with-rest-and-hateoas/
Pass for the second question :) I didn't use that particular framework.
I need to create a RESTful webservice that allows for addressing entities by using different types of IDs. I will give you an example based on books (which is not what I need to process but I want to build a common understanding this way).
Books can be identifier by:
ISBN 13
ID
title
I can create a book by POSTing to /api/v1/books/The%20Bible. This book can then later be addressed by its ISBN /api/v1/books/12312312301 or ID /api/v1/books/A9471IZ1. If I implemented it this way I would need to analyze whatever identifier gets sent and convert it internally.
Is it 'legal' to add the type of identifier to the URL ? Like /api/v1/books/title/The%20Bible?
It seems that what you need is not simply retrieving resources, but searching for them by certain criteria (in your case, by ISBN, title or ID). In that case, rather than complicate your /books endpoint (which, ideally, should only returns books by ID), I'd create a separate /search function. You can then use it search for books by any field.
For example, you would have:
GET /search?title=bible
GET /search?isbn=12312312301
It can even be easily expanded to add more fields later on.
First: A RESTful URl should only contain nouns and not verbs. You can find a lot of best-practices online, as example: RESTful API Design: nouns are good, verbs are bad
One approach would be to detect the id/identifier in code.
The pattern would be, as you already mentioned:
GET /api/v1/books/{id}, like /api/v1/books/12312312301 or /api/v1/books/The%20Bible
Another approach, similar to this.lau_, would be with a query parameter. But I suggest to add the query parameter to the books URL (because only nouns, no verbs):
GET /api/v1/books?isbn=12312312301
The better solution? Not sure…
Because you are selecting “one book by id” (except title), rather than performing a query/search, I prefer the first approach (…/books should return “a collection of books” and .../books/{id} should return only one book).
But maybe someone has a better approach/idea?
Edit:
I suggest to avoid adding the identifier to the URL, it has “bad smell”. But is also a possible approach and I saw that a lot in other APIs. Let’s see if I can find some information on that, if its “ok” or should be avoided.
Edit 2:
See REST API DESIGN - Getting a resource through REST with different parameters but same url pattern and REST - supporting multiple possible identifiers
I am attempting to write a Restful API to control a CMS. There are Objects (e.g., An instance of an Article) and each object has multiple Drafts. To work on an object's Drafts, I built a URL like this:
/cms/objects/{objectId}/drafts/{draftId}
draftIds are not unique unless you provide an objectId.
Hopefully I haven't already messed up with this. But now I have multiple verbs I want to perform on each Draft. Here's a list of verbs:
CLONE, UNPUBLISH, PUBLISH, UNLOCK, LOCK
The way I approached this is to create an endpoint that has an operation query param. And here's an example of how you use it:
POST /cms/objects/3232/drafts/1?operation=CLONE
POST /cms/objects/3232/drafts/1?operation=LOCK
Is there a better way to do this? I'm actually upgrading an already existing API, and the way you used to do something like this is like so:
POST cms/objects/3232/duplicate-draft?source-draft-id=1
POST cms/objects/3232/lock?draft-id=1
I prefer my way, because in my eyes it's more consistent (though I am biased). Is there a better way to do this?
By the way, I am aware of this question that is very similar. The reason I'm creating this new one is that mine is laser focused on the "multiple verb" aspect and his isn't. His is more like, "how do I do multiple verbs and can you teach me lots of other stuff about Restful APIs, too?"
Also, I feel that the accepted answer on that question does not sufficiently address this (see his point 2). For example, my Drafts, do not have a lock=true in their body so I can't easily map the advice from his Change Password section. My Drafts have two fields to represent if the Draft is locked: The user name of the locker and the user id of the locker. It would be inconvenient to have the client pass these both in so my intent above is to abstract that work away from the client.
I'm writing an api. To this point I've been using a route:
http://api.com/resource
and I pass in an action that I want to do to the resource within a json field and go from there. Is this an ideal or preferable situation from both a programmer and user perspective?
Or,
Would something like:
http://api.com/resource/action
be more useful, restful, right (take you pick). Or does it not matter at all? It works as it is, but I'm aiming for public consumption and I'd like to get any problems I'm unaware of with this out of the way before it gets more difficult to change.
Edit:
To add more detail the action I'm not concerned about is of GET, POST, etc. I have a route:
http://api.com/thing
This is a POST route, it creates a thing. Things aren't being stored in a database or anywhere at this point, so the thing created is immediately returned with the response. Users can specify that thing be returned painted a color: red, yellow, or green. From a user perspective, is it more useful to specify the color requirement as part of the post data above or to have routes like:
http://api.com/thing/red
where posting to returns a red thing.
Basically, the action doesn't need to be specified (in the URL or in the data sent) as HTTP verbs, in a REST approach, are used to describe actions to perform on resources. So, your two solutions are not really "REST compliant". What you should do first is combining your route http://api.com/resources with some HTTP verbs in order to:
Create a resource is: POST http://api.com/resources
Read a resource is: GET http://api.com/resources/
Update (replacing actually) a resource is: PUT http://api.com/resources/
Delete a resource is: DELETE http://api.com/resources/
As usual, following conventions is better. Your two solutions are not ideal for a programmer with a taste for conventions and best practices. However, your second solution is readable and explicit. That means if you really want to choose between your two solutions, the second one seems better. But, if you want to update your API to follow more REST conventions, you should consider your resource as a real resource and use HTTP verbs.
I recommend you these two presentations about REST APIs:
http://fr.slideshare.net/Wombert/designing-http-interfaces-and-restful-web-services-dpc2012-20120608
https://speakerdeck.com/u/nicola/p/developing-restful-web-apis-with-python-flask-and-mongodb
You may be interested by this other question and the answer I gave: Resource and Action URI convention for REST.
Edit: according to your new question, send all data as post data, even your color. It will be more consistent. Why should it be different anyway? You should change the URI only if you describe different resources. If the color is just a property of a thing then you don't describe two resources and you should send the color with all other post data.