Look up Envelope by DocumentId? - rest

I'm just getting started with the DocuSign REST API (creating a proof-of-concept integration with my company's product) and am trying to wrap my head around everything. There are a couple things I can't find much info on:
When creating an Envelope, does the documentId matter? I assume if there are multiple documents the documentId for each would need to be different. Is it used anywhere else?
Periodically, I'd like to check the Audit Events for an Envelope. It would be much easier if I could look up the Envelope (or go straight to the Audit Events without looking up the Envelope) with a documentId instead. Is this possible?
Our product already stores documents, and therefore has a documentId - so that is the ID I am using when creating Envelopes. What I'd like to do is, with whatever document I am viewing in our product is check to see if there are any non-completed Envelopes pending. Then I wouldn't need to store any DocuSign related data in our system (i.e. envelopeId).
Can I look up an Envelope by the documentId used to create it?

The documentId is a client defined property and is simply there to help you tag the documents that were used for given envelopes. If you want to track the documents that you're supplying in your envelopes (which it sounds like you are) then you can use it to uniquely identify the underlying docs and if you already have a system that has generated the documentIds then that should make things easier.
No there is not a way to retrieve envelope information through documentId. The best solution is most likely to store a simple table on your side that links documentIds to envelopeIds, then given the documentId you want to search for use the linked envelopeId to retrieve its status.
You should note, though, that there are certain API call limits in place for some API calls and requesting envelope status is one of them. You are not allowed to request status on a given envelope more than 1 once every 15 mins. Instead, the DocuSign Connect module is recommended if you want to track real-time status (DocuSign Connect pushes status out to you as soon as it happens instead of you polling for status every so often).
For more info on API call limits check out the API Best Practices doc in the DocuSign Developer Center under the Go Live section:
https://www.docusign.com/developer-center/go-live/certification

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.

Creating user record / profile for first time sign in

I use an authentication service Auth0 to allow users to log into my application. The application is a Q&A platform much like stackoverflow. I store a user profile on my server with information such as: 'about me', votes, preferences, etc.
When new user signs in i need to do 1 of 2 things:
For an existing user - retrieve the user profile from my api server
For a new user - create a new profile on the database
After the user signs in, Auth0(the authentication service) will send me some details(unique id, name and email) about the user but it does not indicate whether this is a new user(a sign up) or a existing user(a sign in).
This is not a complex problem but it would be good to understand best practice. I can think of 2 less than ideal ways to deal with this:
**Solution 1 - GET request **
Send a get request to api server passing the unique id
If a record is found return it
Else create new profile on db and return the new profile
This seems incorrect because the GET request should not be writing to the server.
**Solution 2 - One GET and a conditional POST request **
Send a get request to api server passing the unique id
The server checks the db and returns the profile or an error message
If the api server returns an error message send a post request to create a new profile
Else redirect to the home page
This seems inefficient because we need 2 requests to achieve a simple result.
Can anyone shed some light on what's best practice?
There's an extra option. You can use a rule in Auth0 to send a POST to the /users/create endpoint in your API server when it's the first time the user is logging in, assuming both the user database in Auth0 and in your app are up-to-date.
It would look something like this:
[...]
var loginCount = context.stats.loginsCount;
if (loginCount == 1) {
// send POST to your API and create the user
// most likely you'll want to await for response before moving on with the login flow
}
[...]
If, on the other hand, you're referring to proper API design and how to implement a find-or-create endpoint that's RESTful, maybe this answer is useful.
There seems to be a bit of disagreement on the best approach and some interesting subtleties as discussed in this post: REST Lazy Reference Create GET or POST?
Please read the entire post but I lean towards #Cormac Mulhall and #Blake Mitchell answers:
The client wants the current state of the resource from the server. It is not aware this might mean creating a resource and it does not care one jolt that this is the first time anyone has attempted to get this resource before, nor that the server has to create the resource on its end.
The following quote from The RESTful cookbook provided by #Blake Mitchell makes a subtle distinction which also supports Mulhall's view:
What are idempotent and/or safe methods?
Safe methods are HTTP methods that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.
Finally this key distinction is made in Section 9.1.1 of the HTTP specification:
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects,
so therefore cannot be held accountable for them.
Going back to the initial question, the above seems to support Solution 1 which is to create the profile on the server if it does not already exist.

HTTP GET setting internal data, still considered RESTful?

As I understand it, a HTTP GET request should return the requested data and is considered RESTful if safe (read-only) and idempotent (no side effects).
However, I would like to implement a service to show new items since last visit using an URI of /items/userid/new, can that in any way be RESTful?
When returning the data, the items sent in response to the GET request should be marked as read in order to keep track of what is new. Marking these items will violate both the safe requirement and the idempotent requirement.
Does that mean .../new is never considered RESTful?
Very interesting question. I think the answer would be "depends on the implementation" since there are different solutions that would all meet the business requirement.
If every visit to the URL /items/userid/new by the same user modifies the DB records, then it's not a "safe method" and would not fit the commonly accepted REST pattern.
If you're filtering for the new items on the view, but without any corresponding DB changes with each GET call, then it would certainly be RESTful. For example:
/items/userid/new?lastvisit=2015-12-31
or
/items/userid/new?last_id=12345
or storing the list of viewed items on the client side would certainly qualify.
Normally we decide the restful service and associate protocol methods to it. In case of HTTP it is we use GET,POST,PUT...etc. Normally Get is used get some application state that will rendered with hyper text.
Here /items/userid/new can be new service that returns the list. Any modification on this list will be subsequent request with different method association.
Keeping track of already visited items should not be the server's responsibility. The client should rember already visited items. That leads to better scalability and loosy coupled systems as the server must not handle these parameters for e.g. thousand of clients.
To deliver fresh items you could, as Cahit already touched, provide a feed that includes all items for either a time frame or a fixed number of items. Generally an archived feed is a good choice.
As a result of this a client can crawl your feed on its own to retrieve all new items.
Interesting question indeed.
For a plain url, I would not do it. One reason for example: I remember sending a testmail with a unique link pointing to our own webserver. While passing through the ISP's mailserver, a request was made with that url to our server.. This was done by a spamfilter to check if the url existed.. So, if a mail was sent to the customer saying 'look here for the new items', those would be gone even before the mail was received.
And you certainly wouldn't want that plain url to appear in search results somewhere, or be used for preloading pages.
On the other hand, if the request was made during login (or using a cookie), it could be ok.
Maybe that's what SO does when we view our statistics/responses.

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?"

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.