I can access both the RSA REST and WSDL based APIs. Their documents refer to content and resourses. However, when logging into the actual tool I can access things like incident ticket and the like.
Incidents tickets will have INC-1234 which would be a string. But the API takes integer values for either content or resource when searching by ID.
self.wsdl['search'].service.SearchRecordsByReport(
sessionToken=self.token,
reportIdOrGuid=14,
pageNumber=1
)
If I don't provide an integer i get a 404 with a simple
"Message": "The request is invalid." in the REST
and something a little more complex if i pass a value like that in SOAP
So, Question 1. is there an RSA resource that correlates/demystifies the relationships of calls in the API with the actual names of things I'm dealing with the in the UI.
Question 2. Is there a code library were someone has created/modified rsa incident tickets before out there?
If you're talking about getting the record contentID you can get it two ways, in the GUI hover over your key field (the clickable link) and in the bottom left corner of archer it'll show something similar to "123456|100|17" where the first set is the contentID of that record.
If you're talking about getting a reportID (14 like you've shown above) you can do the same thing when you go to the master reports list, and it'll show in the bottom right corner of your browser.
If you want to do it all from code I usually piece it together like this:
Execute a search of a report; Get the field IDs from the report <FieldDefinition> (it's probably important to make sure your keyfield is included on the report GUI so you'll be able to identify which record you're dealing with); make another API call (probably REST since it really handles the metadata) to get the field name etc. (or you could make it all static and just hard-code the field names with the corresponding GUIDS)
Within the <Record> tag, you can snag the contentID attribute. Then take a step down and compare the field tag that matches your keyfield and you'll have the contentID of that record.
Make record updates, deletes, etc whatever you need to do.
If you're looking for a specific report ID, make a REST call to get all reports, and it'll return report names and IDs, and then go about your business making your other calls.
I've recently came across similar situation where I have to search for a field value (e.g. "INC-1234") using Archer's API.
So, for your Question 1:
The method that I found convenient to my requirements is "ExecuteQuickSearchWithModuleIds" which can search for a value and provides all ContentIDs that have those values (given the ModuleId).
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ExecuteQuickSearchWithModuleIds xmlns="http://archer-tech.com/webservices/">
<sessionToken>ABC123ABC123ABC123ABC123ABC1</sessionToken>
<moduleIds>123</moduleIds>
<keywords>INC-1234</keywords>
<pageNumber>9999999</pageNumber>
<pageSize>9999999</pageSize>
</ExecuteQuickSearchWithModuleIds>
</soap:Body>
</soap:Envelope>
And for your Question 2, I found a rich library for Python3 Archer RSA.
Hope this helps someone who lands on this question.
Related
What's the equivalent REST method and request for this sql query?
UPDATE user
SET email = 'newemail#etc.com'
WHERE email = 'oldemail#etc.com'
AND account_number = 1234
Would it be
PATCH api/users/1234/oldemail#etc.com
{
email:"newemail#etc.com"
}
or should I create a new method, something like this?
PATCH api/update-email/1234
{
oldEmail:"oldemail#etc.com",
newEmail:"newemail#etc.com"
}
Note: the account_number is not the primary key id
You are updating an existing record, you should use PATCH instead of POST.
Refs:
RESTful API Design — PUT vs PATCH
REST – PUT vs POST
RESTful API Design: 13 Best Practices to Make Your Users Happy
What's the equivalent REST method and request for this sql query?
How would you do it on a web page? You'd POST form data.
For instance, if you were to
GET /emailAddresses
and then you happened to notice that there was a mistake in the list that you wanted to fix, you would probably click on the "fix this email" link, which would load a new form
GET /fixThisEmail?oldEmail=oldemail#example.com
And then you would fill in the replacement address into the form (which would have the original address preloaded into an input control). Since the /emailAddresses resource is the cachable data that you want to change, the form submission would probably look like
POST /emailAddresses
Content-Type: application/x-www-form-urlencoded
oldEmail=oldemail#example.com&newEmail=newemail#example.com
If instead you wanted to use a remote authoring idiom, you might reasonably edit your own local copy of the email addresses list to correct the error, and then send the revised representation back to the server
GET /emailAddresses
(make the edit in your local copy)
PUT /emailAddresses
PATCH is convenient when the list is much bigger than the http headers and the edit is small relative to the size of the list.
GET /emailAddresses
(make the edit in your local copy)
PATCH /emailAddresses
... but, notice that for both PUT and PATCH, you are going to need to figure out how to extract from the request-body the things that have changed, and compute the right SQL update query to use. Getting the "old" email address to match on may be painful if it isn't present in the new representation.
You can make that somewhat simpler by using a bespoke patch document representation, but that restricts the range of general purpose clients that can use your API.
I am trying to create a REST call in soapUI with a field that can be repeated. Does anyone know how to make this work? I can't seem to create a 2nd field with the same name and get an error when trying to add all the values in the single field.
ie, I am trying to send an email to multiple people
Trying to find answer to same question I found this link from soapUI support forum which gives the answer.
There is property "Multi-value delimiter" in Request Properties in soapUI (bottom left corner). You need to specify this delimiter (for example "|") and then you can provide multiple values in soapUI using the delimiter which you specified (example: one|two|three, will send array of three elements: one, two, three).
Let's say I have an object, Widget, comprised of an Id and a Name. Let's say I expose an endpoint, /widget, where clients can POST new Widget objects. If I want the Id field to always be set by the server, not modifiable by the client, but still visible to clients, how can I declare that the Id field is not modifiable? I'm using RESTeasy if that makes any difference.
I can think of a few options.
First, are you sure you need to expose the ID as part of the representation? Or is it enough to respond with the location of the new posted resource?
Your client posts:
<Resource><Name>New Resource</Name></Resource>
And you respond:
HTTP/1.1 201 Created
...
Location: /resources/{new_resource_id}
Beyond that, I think it's OK to have some simple, well-understood conventions with your clients. I think most developers understand that an ID is likely to be system-generated (especially, since you're doing a POST and not a PUT). For less obvious cases, where you have arbitrary read-only fields (or other validation or display information), I think it may make sense to provide a link to metadata:
<NewPersonForm>
<atom:link href="/people/new/metadata" rel="/rels/metadata" />
<Name />
<Department>HR</Department>
</NewPersonForm>
What the metadata looks like is up to you, but something along these lines might work for you:
<Metadata>
<Element>
<Name>Department</Name>
<IsReadOnly>True</IsReadOnly>
</Element>
</Metadata>
That's a nice, format-neutral (it works well for both XML and JSON) way to provide information to the client, and if they really want to, they can program against it to build forms on the fly (I use it to provide validation information, language-specific labels, and data type information).
I hope this helps.
John
You write the code on the server that free to do whatever it wants. And that includes adding or changing data as needed. Check the AtomPub protocol section 9.2 that explicitly states:
Since the server is free to alter the
POSTed Entry, for example, by changing
the content of the atom:id element,
returning the Entry can be useful to
the client, enabling it to correlate
the client and server views of the new
Entry.
According to REST style, it's generally assumed that HTTP POST, GET, PUT, and DELETE methods should be used for CREATE, READ, UPDATE and DELETE (CRUD) operations.
But if we stick to the HTTP method definitions, it might not be so clear.
In this article it's explained that:
In a nutshell: use PUT if and only if you know both the URL where the resource will live, and the entirety of the contents of the resource. Otherwise, use POST.
Mainly because
PUT is a much more restrictive verb. It takes a complete resource and stores it at the given URL. If there was a resource there previously, it is replaced; if not, a new one is created. These properties support idempotence, which a naive create or update operation might not. I suspect this may be why PUT is defined the way it is; it's an idempotent operation which allows the client to send information to the server.
In my case I usually issue updates passing all the resource data, so I could use PUT for updates, but every time I issue an update I save a LastUser and LastUpdate column, with the user id that made the modification and the time of the operation.
I'd like to know your opinion, because strictly speaking those two columns are not part of the resource, but they do prevent the operation from being idempotent.
Ignoring the comment about the REST style mapping CRUD to the HTTP methods, this is an excellent question.
The answer to your question is, yes you are free to use PUT in this scenario even though there are some elements of the resource that are updated by the server in a non-idempotent manner. Unfortunately, the reasoning behind the answer is quite vague. The important thing, is to understand what was the intent of the client request. The client intended to completely replace the contents of resource with the values passed. The client is not responsible for the server doing other operations and therefore the semantics of the HTTP method are not violated.
This is the reasoning that is used to allow a server to update a page counter when you do a GET operation. The client didn't ask for an update therefore the GET is safe even though the server chose to make an update.
The whole, complete resource versus partial resource debate has finally been spelled out in an update to the HTTP spec
An origin server SHOULD reject any PUT
request that contains a
Content-Range header field, since it
might be misinterpreted as partial
content (or might be partial content
that is being mistakenly PUT as a
full representation). Partial content
updates are possible by targeting a
separately identified resource with
state that overlaps a portion of
the larger resource, or by using a
different method that has been
specifically defined for partial
updates (for example, the PATCH
method defined in [RFC5789]).
So, what we are supposed to do is now clear. What is not so clear is why there exists this constraint on only being allowed to send full responses. That question has been asked and IMHO remains unanswered in this thread on rest-discuss.
As LastUser and LastUpdate are not modifiable by the client, I'd remove them from the representation of your resource altogether. Let me explain my reasoning with an example.
Let's say that our typical example API will return the following representation to the client when asked to provide a single resource:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>ipsum</lorem>
<dolor>sit amet</dolor>
<lastUser uri="/user/321">321</lastUser>
<lastUpdate>2011-04-16 20:00:00 GMT</lastUpdate>
</example>
If a client wants to modify the resource, it would presumably take the whole representation and send it back to the API.
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUser>322</lastUser>
<lastUpdate>2011-04-16 20:46:15 GMT+2</lastUpdate>
</example>
Since the API generates values for lastUser and lastUpdate automatically and cannot accept data provided by the client, the most appropriate response would be 400 Bad Request or 403 Forbidden (since the client cannot modify these values).
If we want to be compliant with REST and send a full representation of the resource when doing a PUT request, we need to remove lastUser and lastUpdate from the representation of the resource. This will allow clients to send the full entity via PUT:
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
The server would accept a full representation now that it doesn't contain lastUpdate and lastUser.
The question that remains is how to provide clients with access to lastUpdate and lastUser. If they don't need it (and these fields are required just internally by the API), we are fine and our solution is perfectly RESTful. If however clients need access to this data, the cleanest approach would be to use HTTP headers:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
X-Last-User: /user/322
...
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
Using a custom HTTP header is not ideal because user agents need to be taught on how to read it. If we want to provide clients with access to the same data in a more easier way, the only thing that we can do is to put the data into the representation, and we are facing the same problem as in your original question. I would at least try to mitigate it somehow. If the content type used by the API is XML, we can put the data into node attributes instead of exposing them directly as node values, i.e.:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
...
<?xml version="1.0" encoding="UTF-8" ?>
<example last-update="2011-04-16 18:46:15 GMT" last-user="/user/322">
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
This way we'll at least avoid the problem where a client would attempt to submit all XML nodes in a follow-up PUT request. This won't work with JSON, and the solution is still a bit on the edge of idempotency (since the API would still have to ignore the XML attributes when processing the request).
Even better, as Jonah pointed out in the comments, if clients need access to lastUser and lastUpdate, these can be exposed as a new resource, linked from the original one e.g. as follows:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUpdateUri>/example/123/last-update</lastUpdateUri>
</example>
... and then:
GET /example/123/last-update
<?xml version="1.0" encoding="UTF-8" ?>
<lastUpdate>
<resourceUri>/example/123</resourceUri>
<updatedBy uri="/user/321">321</updatedBy>
<updatedAt>2011-04-16 20:00:00 GMT</updatedAt>
</lastUpdate>
(The above can be also nicely expanded to provide a full audit log with individual changes, providing a resource changelog is available.)
Please note:
I agree with Darrel Miller's take on the question, but I wanted to provide a different approach on top of it. Note that this approach is not backed-up by any standards/RFCs/etc, it's just a different take on the problem.
The disadvantage of using PUT to create resources is that the client has to provide the unique ID that represents the object it is creating. While it usually possible for the client to generate this unique ID, most application designers prefer that their servers (usually through their databases) create this ID. In most cases we want our server to control the generation of resource IDs. So what do we do? We can switch to using POST instead of PUT.
So:
Put = UPDATE
Post = INSERT
Hopefully, this helps for your specific case.
The HTTP methods POST and PUT aren't the HTTP equivalent of the CRUD's create and update. They both serve a different purpose. It's quite possible, valid and even preferred in some occasions, to use PUT to create resources, or use POST to update resources.
Use PUT when you can update a resource completely through a specific resource. For instance, if you know that an article resides at http://example.org/article/1234, you can PUT a new resource representation of this article directly through a PUT on this URL.
If you do not know the actual resource location, for instance, when you add a new article, but do not have any idea where to store it, you can POST it to an URL, and let the server decide the actual URL.
Let's say I have a RESTful, hypertext-driven service that models an ice cream store. To help manage my store better, I want to be able to display a daily report listing quantity and dollar value of each kind of ice cream sold.
It seems like this reporting capability could be exposed as a resource called DailyReport. A DailyReport can be generated quickly, and there doesn't seem to be any advantage to actually storing reports on the server. I only want a DailyReport for some days, other days I don't care about getting a DailyReport. Furthermore, storing DailyReports on the server would complicate client implementations, which would need remember to delete reports they no longer need.
A DailyReport is transient; its representation can be retrieved only once. One way to implement this would be to offer a link "/daily-reports", a POST to which will return a response containing a DailyReport representation listing the information for that day's sales.
Edit: Let's also say that I really do want to do a POST request. A DailyReport has many different options for creating a view such as sorting ice cream types alphabetically, by dollar value - or including an hourly breakdown - or optionally including the temperature for that day - or filtering out certain ice cream types (as a list). Rather than using query parameters with a GET, I'd rather POST a DailyReport representation with the appropriate options (using a well-defined custom media type to document each option). The representation I get back would display my options along with the report itself.
Is this the correct way to think about the problem, or should some other approach be used instead? If correct, what special considerations might be important when implementing the DailyReport resource? (For example, it probably wouldn't be appropriate to set the Location header when returning after a POST request).
If you want to make daily reports for past days available, you could implement it as a GET to /daily_reports/2009/08/20. I agree with John Millikin that a POST is unnecessary here - there's no need for something like this to be a user-creatable resource.
The advantage of making the report for each day available as its own URI is cacheability.
EDIT: A good solution might be to merge the two answers, making daily_report/ a no-cache representation of the current day's data and daily_reports/yyyy/mm/dd a cacheable representation of a full day's data.
There's no need to use a POST for this, since requesting the report doesn't change the state of the server. I would use a resource like this:
GET /daily-report/
200 OK
Pragma: no-cache
<daily-report for="2009-04-20" generated-at="2009-4-20T12:13:14Z">
<!-- contents of the report here -->
</daily-report>
Responding to your edit: if you are POSTing a description of the report to a URL, and retrieving a temporary data set as a result, that's not REST at all. It's RPC, in the same vein as SOAP. RPC is not an inherently bad thing, but please, please don't call it RESTful.
Sometimes it is desirable to keep a record of requests for reports, in those cases it is not unreasonable to POST to a collection resource. It is also useful for long running reports where you want handle the execution asynchronously. How long the server holds onto those report requests is up to you.
I would do something like
POST /DailyReportRequests
which would return a representation of the request, including options, and when the report is completed, a link to the report results.
Another alternative which is good when you have a set of pre-canned reports is to create a DailyReports resource that contains a list of preconfigured report links. The OpenSearchDescription spec allows you to do something similar to this using the Query tag.
I think Greg's approach is the correct one. To expound upon it, I don't think you should provide a /daily-report resource that changes daily, because running the report on Tuesday at 11:59 would yield different results than running it Wednesday at 00:01, which can be A) confusing for clients expecting the resource to be the same, and B) doesn't allow clients to retrieve a previous day's data after the day has passed. You should provide a unique resource identifier for each daily report that's available, that way clients can access the information they need at any time.