Dialogflow agent entities to be contacted through REST APIs - rest

I am developing an agent, and have an entity within the agent.
now what i need is to add some new details to the entity, but not by opening dialogflow.
I want to make a REST API to add it for me.
Is it possible?

It sounds like you're looking for the API to either create or patch entities.

From reading the docs, it doesn't look like this is possible via HTTP requests.
You could try automated expansion:
Automated expansion of developer entities allows an agent to recognize
values that have not been explicitly listed in the entity.
If a user's request includes an item that isn't listed in the entity,
automatic expansion recognizes the undefined item as a parameter in
the entity. The agent sees the user's request is similar to the
examples provided, so it can derive what the item is in the request.
For example, consider a shopping list with items to buy:
If a user says "I need to buy some vegetables", "vegetables" will be
picked up as a value, even though it's not included in the #item
entity. With automated expansion enabled, the agent sees the user's
query is similar to the training phrases provided in the intent and
can pick out what should be extracted as a new value.
The closer the user's input is to the examples provided in the
training phrases section, the better the results the automated
expansion feature provides. This is another reason to provide as many
examples as possible.

Related

REST endpoint for complex actions

I have a REST API which serves data from the database to the frontend React app and to Android app.
The API have multiple common endpoints for each model:
- GET /model/<id> to retrieve a single object
- POST /model to create
- PATCH /model/<id> to update a single model
- GET /model to list objects
- DELETE /model/<id> to delete an object
Currently I'm developing an Android app and I find such scheme to make me do many extra requests to the API. For example, each Order object has a user_creator entry. So, if I want to delete all the orders created by specified user I need to
1) List all users GET /user
2) Select the one I need
3) List all orders he created GET /order?user=user_id
4) Select the order I want to delete
5) Delete the order DELETE /order/<id>
I'm wondering whether this will be okay to add several endpoints like GET /order/delete?user=user_id. By doing this I can get rid of action 4 and 5. And all the filtering will be done at the backend. However it seems to me as a bad architecture solution because all the APIs I've used before don't have such methods and all the filtering, sorting and other "beautifying" stuff is usually at the API user side, not the backend.
In your answer please offer a solution that is the best in your opinion for this problem and explain your point of view at least in brief, so I can learn from it
Taking your problem is in isolation:
You have an Order collection and a User collection
User 1..* Orders
You want to delete all orders for a given user ID
I would use the following URI:
// delete all orders for a given user
POST /users/:id/orders/delete
Naturally, this shows the relationship between Users & Orders and is self-explanatory that you are only dealing with orders associated with a particular user. Also, given the operation will result in side-effects on the server then you should POST rather than GET (reading a resource should never change the server). The same logic could be used to create an endpoint for pulling only user orders e.g.
// get all orders for a given user
GET /users/:id/orders
The application domain of HTTP is the transfer of documents over a network. Your "REST API" is a facade that acts like a document store, and performs useful work as a side effect of transferring documents. See Jim Webber (2011).
So the basic idioms are that we post a document, or we send a bunch of edits to an existing document, and the server interprets those changes and does something useful.
So a simple protocol, based on the existing remote authoring semantics, might look like
GET /orders?user=user_id
Make local edits to the representation of that list provided by the server
PUT /orders?user=user_id
The semantics of how to do that are something that needs to be understood by both ends of the exchange. Maybe you remove unwanted items from the list? Maybe there is a status entry for each record in the list, and you change the status from active to expired.
On the web, instead of remote authoring semantics we tend to instead use form submissions. You get a blank form from somewhere, you fill it out yourself, you post it to the indicated inbox, and the person responsible for processing that inbox does the work.
So we load a blank form into our browser, and we make our changes to it, and then we post it to the resource listed in the form.
GET /the-blank-form?user=user_id
Make changes in the form...
POST ????
What should the target-uri be? The web browser doesn't care; it is just going to submit the form to whatever target is specified by the representation it received. One answer might be to send it right back where we got it:
POST /the-blank-form?user=user_id
And that works fine (as long as you manage the metadata correctly). Another possibility is to instead send the changes to the resource you expect to reflect those changes:
POST /orders?user=user_id
and it turns out that works fine too. HTTP has interesting cache invalidation semantics built into the specification, so we can make sure the client's stale copy or the orders collection resource is invalidated by using that same resource as the target of the POST call.
Currently my API satisfies the table from the bottom of the REST, so, any extra endpoint will break it. Will it be fatal or not, that's the question.
No, it will be fine -- just add/extend a POST handler on the appropriate resource to handle the new semantics.
Longer answer: the table in wikipedia is a good representation of common practices; but common practices aren't quite on the mark. Part of the problem is that REST includes a uniform interface. Among other things, that means that all resources understand the same message semantics. The notion of "collection resources" vs "member resources" doesn't exist in REST -- the semantics are the same for both.
Another way of saying this is that a general-purpose component never knows if the resource it is talking to is a collection or a member. All unsafe methods (POST/PUT/PATCH/DELETE/etc) imply invalidation of the representations of the target-uri.
Now POST, as it happens, means "do something that hasn't been standardized" -- see Fielding 2009. It's the method that has the fewest semantic constraints.
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. -- RFC 7231
It's perfectly fine for a POST handler to branch based on the contents of the request payload; if you see X, create something, if you see Y delete something else. It's analogous to having two different web forms, with different semantics, that submit to the same target resource.

Do Google Actions have unique ids?

When developing for Alexa, every skill has a unique Id. This allows me to develop multiple skills, using the same lambda / codebase, that return unique info based on the skill id.
However, from what I've seen with Google Assistant, Actions don't have ids. Requests include a unique userId and the conversationId. And Responses include an intent id -- but there's no way to identify the action itself.
Any ideas / pointers to things I may have missed?
There are a few ways you can approach this, depending on what platform you're using for your webhook.
For both Dialogflow and the Action SDK, you can always specify a unique query parameter as part of the webhook or even have different path portions of the webhook go to the same lambda and examine either the query value or the path. This has the benefit that you're in full control of what the possible values are.
If you're using Dialogflow, there is a unique IntentID for each Intent that comes through. This might be one way to track which one has been invoked. But this seems somewhat kludgy.
Also for Dialogflow, you can set unique headers in the Dialogflow console, and then examine the value of these headers in your webhook. Again, this has the advantage of giving you control of the value.
The Action SDK doesn't have that feature, but it does transmit a JWT token in the Authorization header. This token is for verifying it has come from the correct project (and from Google), but once you've decoded it (and verified it), the aud field should contain the same project ID as the project in the Action Console.

Updating something in REST

Philosophically, I had questions about some examples on how to tackle the following REST scenarios:
1) A user who is signed in wants to 'favorite' someone's blog posting. The user id is a guid and the blog posting is a guid. Should this be a PUT because user/blog exist, or POST because there is no entry in the 'favorites' table?
2) A security row in the DB consists of 10+ properties, but I'd only want to update one part of the entity (# of failed login attempts for a user). What should the call be? Pass the entire data transfer object in JSON? Or just add a new api route for the specific action to update? I.e. a PUT with just one parameter (the # of login attempts) and pass the id of the user.
3) Similar to #2, a user class (consisting of 25+ properties) but I'd only like the user to update a specific part of the class, not the whole thing. Philosophically do I need to pass the entire user object over? Or is it OK to just update one thing. It seems I could get crazy and make lots of specific calls for specific properties, but the reality is I will probably only update 2-3 specific parts of the user (as well as obviously updating the whole thing in other cases). What's the approach here for updating specific parts of an entity in the DB?
Thanks so much
Use a POST if you don't have an ID/UUID yet.
The resource is the security record. Do a PUT on that ID, and pass a block of the properties to be changed.
Ditto (2). You should get whatever parameters will help you identify that record in the DB. If it's unsavory to send these in the POST request and you're doing AJAX, just stash them in the session.
With REST, everything is about updating discrete resources ("nouns"). It's up to you how you want to assign these, but a simple interface that uses verbs ("PUT", "GET", "DELETE", etc..) sensibly, returns relevant HTTP codes, and is easy for others to implement is the best way to go.
So, just ask yourself, "What nouns do I want to give CRUD to, and am I going to exhaust people who wish to consume my API?"

How to design REST API for non-CRUD "commands" like activate and deactivate of a resource?

Before I decided to ask this question I have searched quite a long for the answer but I haven't found any satisfactory. (e.g. Examples of the best SOAP/REST/RPC web APIs? And why do you like them? And what's wrong with them?)
And the problem is actually quite simple. I have an object/resource named Account. My REST API supports all CRUDs with GET, POST, PUT and DELETE already with proper error handling, status codes etc.
Additionally however I want to expose an API ("command") to activate and deactivate selected Account resource.
Even if the "isActive" is a property of the Account I don't want to use just the Update from my CRUD of the whole Account.
I know it is easy to violate REST principles and make RPC style design with such design like this:
PUT /api/account/:accountId/activate
PUT /api/account/:accountId/deactivate
So what is the best solution for this use case?
My current idea is to use PUT and DELETE verbs like this (to treat it as a sub-resource) as proposed here http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful:
PUT /api/account/:accountId/isActive // for activate
DELETE /api/account/:accountId/isActive // for deactivate
What are your solutions?
How about coming up with a noun for the feature you want to modify - 'status' in this instance. This would then become a sub resource of the parent entity. So for your case I would model the URI as follows:
/api/accounts/{accountId}/status
If the 'update' semantics are idempotent then PUT would be most appropriate, else that would need to be a POST (e.g if nonces are involved and are invalidated by the service). The actual payload would include a descriptor for the new state.
Note, I pluralized 'accounts' since you can have multiple of those, but status is singular since your account can have only one state.
PATCH is the most appropriate method in this case. Please find more at RESTful URL for "Activate"
The POST method would create the resource 'account'. Active can be seen as one of the properties of the resource 'account'. Hence it should be a PUT request.
I would say even deactivate must be a PUT request as the account resource will still exist.
To activate an account you can set a property on the resource. That is:
/api/account/{accountId}?activate=true
To deactivate:
/api/account/{accountId}?activate=false
A GET request on the account would return a JSON with the activate value in it.
A DELETE request should completely delete the account resource.
First off, PUT is appropriate compared to POST, because you are creating a resource to an already-known location. And, I think, there's no dilemma about DELETE. So at first glance, your current approach seems to beat the alternatives.
I used to think the same way, until I implemented my own REST api, in which I wanted the admin to be able to set an account in a deactivated - yet not deleted, just "banned" - state. When I gave it a little more thought, I decided to do it vice versa.
Let me explain. I like to see the activation resource as "the option to activate the account". So if a url like /account/foo/activation exists, it could only mean that the account is not activated and the user has the right to activate it. If it doesn't exist, the account is either already activated or in a banned state.
Consequently, the only rational thing to do in order to activate the account is to try and DELETE the resource. And, in order to enable activation, an admin would have to PUT an activation resource.
Now, the question that comes to mind is how do you distinguish a banned account from an already activated one. But since a ban could be seen as a resource too, you could create a /account/foo/ban resource collection. In order to ban an account, probably for a fixed amount of time, you just POST a resource under that collection, containing all the details of the ban.

Is there a GitHub API to get autocomplete suggestions for user/organization name?

I know how to get the list of organizations for a user.
However, I want to let the user type in the user/organization name and provide autocomplete for that name where the autocomplete includes all user/organizations, not just the organizations they belong to.
It would be too long to get the entire list (and I am not sure that GitHub even exposes that), but the top 5-20 for any given prefix is all I want.
The Search API smells more like a single transaction search and not an autocomplete API, so while I could use it, most likely it would hit the rate limit too often and give a bad UX.
There is something close to this with https://github.com/autocomplete/users?q=prefix, but that is not part of the official GitHub API, so I know that the back end does support these kind of queries... I am just not finding it from the API documentation, and I don't want to access a non-API URL.
GitHub does not do this for you and likely never will. One option you have is to construct a service like that yourself and constantly update your list of users. One way to update the list of users (sanely) is to do the following:
Make an initial GET to /users?per_page=100
Save the ETag header that's returned and use pagination to get all of the most recent ones
On future requests send along the ETag and when there are new users, save the newest ETag.
Repeat.
So you'll be able to then build an auto-completion service yourself so long as you keep your listing of GitHub users up-to-date.
Also note, that sending along the ETag will save your ratelimit if there is nothing new to return.