Even though I'm setting Compavility version in request header (967), when I'm making a call (GeteBayDetails in that case), the response comes with version higher than I need and want (979). These applies to both app I'm currently developing and even API Test Tool. Is there something that I'm missing? Or the Version tag in response isn't related to Compability Level?
Header:
X-EBAY-API-SITEID:212
X-EBAY-API-COMPATIBILITY-LEVEL:967
X-EBAY-API-CALL-NAME:GeteBayDetails
Body:
<?xml version="1.0" encoding="utf-8"?>
<GeteBayDetailsRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>...</eBayAuthToken>
</RequesterCredentials>
</GeteBayDetailsRequest>
And the response:
<?xml version="1.0" encoding="UTF-8"?>
<GeteBayDetailsResponse
xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2016-09-27T11:21:41.341Z</Timestamp>
<Ack>Failure</Ack>
<Errors>
<ShortMessage>Nieznany błąd.</ShortMessage>
<LongMessage>Nieznany błąd.</LongMessage>
<ErrorCode>17460</ErrorCode>
<SeverityCode>Error</SeverityCode>
<ErrorClassification>RequestError</ErrorClassification>
</Errors>
<Version>979</Version>
<Build>E979_INTL_API_18061441_R1</Build>
</GeteBayDetailsResponse>
PS. As far as I know, request fails because of the newer version of the API. And worked before like a charm. Thats why I want to stick to 967.
What you are seeing is normal behavior in that the response will always contain the most recent API schema that could service your request. I encounter many calls for which there are no applicable execution differences between the requested schema and the performing schema, for a given particular request. Also this returning "latest schema version that could service the API request" behavior is how you can determine if you can move up your compatibility level safely, as support drops off periodically.
Of course when the response has a lower schema than the latest in the release notes for the API, then you know you are in a situation where at some point you have to change your code to reflect what has been deprecated or changed before the support for the last schema that can service your particular request ends.
This eBay DTS article mentions this Information in the API Response
as well as going over the eBay API schema versioning process.
Also, be sure on XML POST requests to specify the API schema version in the request itself using the Version tag, not just the HTTP header as with the example call code for the GeteBayDetails API documentation:
<?xml version="1.0" encoding="utf-8"?>
<GeteBayDetailsRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<!-- Call-specific Input Fields -->
<DetailName> DetailNameCodeType </DetailName>
<!-- ... more DetailName values allowed here ... -->
<!-- Standard Input Fields -->
<ErrorLanguage> string </ErrorLanguage>
<MessageID> string </MessageID>
<Version> string </Version>
<WarningLevel> WarningLevelCodeType </WarningLevel>
</GeteBayDetailsRequest>
Hope this helps
Related
I'm running XACML using the Authzforce PDP engine and a configuration pdp.xml file, that looks like:
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0"
version="6.0.0">
<rootPolicyProvider id="rootPolicyProvider"
xsi:type="StaticRootPolicyProvider" policyLocation="${PARENT_DIR}/policy.xml" />
</pdp>
Now, the file ${PARENT_DIR}/policy.xml, that is read by the PDP engine through the rootPolicyProvider contains the actual XACML policies and is becoming fairly large. So, I would like to divide the XACML policies in multiple files policy1.xml, policy2.xml, policy3.xml, etc. These files then need to be read by the PDP engine.
Does anyone know whether the PDP engine configuration xml-file is able to specify this using multiple policyProviders or otherwise? It shouldn't be too difficult, but I have not found any solution yet after a few hours of search on the web.
Looking forward to your replies.
Thx, Jack.
For this use case, I recommend to upgrade to AuthzForce Core 14.0.0 or later. Then you have two options (beware the XML schema and namespace have changed a bit):
Multiple 'policyLocation' elements, for example:
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/7.0" version="7.0.0">
<policyProvider id="refPolicyprovider" xsi:type="StaticPolicyProvider">
<policyLocation>${PARENT_DIR}/policy1.xml</policyLocation>
<policyLocation>${PARENT_DIR}/policy2.xml</policyLocation>
</policyProvider>
<rootPolicyRef>policy1</rootPolicyRef>
</pdp>
Use a wildcard pattern as 'policyLocation', for example (including all policy files with '.xml' extension):
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/7.0" version="7.0.0">
<policyProvider id="refPolicyprovider" xsi:type="StaticPolicyProvider">
<policyLocation>${PARENT_DIR}/*.xml</policyLocation>
</policyProvider>
<rootPolicyRef>policy1</rootPolicyRef>
</pdp>
In both cases, the 'rootPolicyRef' identifies the root policy (where the PDP evaluation starts). In this case, the root policy is supposed to combine the other policies, i.e. be a XACML PolicySet with a defined PolicyCombiningAlgId and one or more PolicyIdReferences or PolicySetIdReferences to the other policies.
You can find a full example using the wildcard option on authzforce github.
Also you can find more info about the PDP configuration format (latest version) in the XML schema.
I'm trying to upload a file to SharePoint programmatically via a Mac Application that I am currently writing. I can use the GetListItems webservice to retrieve a list of files, and all authentication etc works correctly. I form the SOAP message myself as follows:
At first I thought I just had the Objective C side written incorrectly, but I've been using the HTTP request extension for Firefox, 'Poster', and still can't get it to work.
The soap message in Poster that I construct is:
<?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>
<CopyIntoItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<SourceUrl>http://null</SourceUrl>
<DestinationUrls>
<string>myurl.com/Shared Documents/Documents/TestingFile.txt</string>
</DestinationUrls>
<Stream>VGVzdGluZyB0ZXN0aW5n</Stream>
</CopyIntoItems>
</soap:Body>
</soap:Envelope>
The stream (at the moment) is just some data, to see if I can get it to work. I read that setting the SourceUrl as http://null, can help in some instances. I also read that the DestinationURL needs to be the full path. The problem here is:
1) If I put the URL without https:// then I get a response of:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><CopyIntoItemsResponse
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<CopyIntoItemsResult>0</CopyIntoItemsResult><Results><CopyResult ErrorCode="Success"
DestinationUrl="myurl.com/Shared Documents/Documents/TestingFile.txt" /></Results>
</CopyIntoItemsResponse></soap:Body></soap:Envelope>
2) If I put the full path, e.g.
https://myurl.com/Shared Documents/Documents/TestingFile.txt
then the result tells me the same as before, except for this bit:
<CopyResult ErrorCode="Unknown" ErrorMessage="Object reference not set to an instance of an
object."
DestinationUrl="https://dbp.btfinancialgroup.com/Shared%20Documents/Papers/TestingFile.txt"
/>
3) If I put the full path, in quotes, e.g.
"https://myurl.com/Shared Documents/Documents/TestingFile.txt"
then the results tell me the same as the first, e.g. that it was successful, but with
a destinationURL of this:
DestinationUrl=""https://dbp.btfinancialgroup.com/Shared
Documents/Papers/TestingFile.txt""
In ALL of these scenarios, the file does not exist in the destination at the end of the request.
I'm really stuck, as most online suggestions are for remedying C# problems, which use the .net protocols for connecting to SharePoint.
Any suggestions?
Thanks
To assist in anyone else who may come across this problem.
It turned out not to be an issue with my code at all, which I established by making a C# project to try and use the better connectivity it provides to SharePoint, and also spoke to someone in Microsoft Support who confirmed my code should work.
In the end, it was incorrect mappings on the server, which meant the web service never linked correctly to the URLs. This caused the "Object reference not set to an instance of an object" error.
To anyone else receiving this error message, it may not lie just in a problem with the values you are passing to the web service - also check the mappings set up on the server. Apparently the ULS logs may help with this, the Microsoft support guy mentioned, in terms of narrowing down what's causing it.
I am creating a REST web service that returns XML documents by serializing .NET objects using the DataContractSerializer. It works very nicely returning documents like:
<?xml version="1.0" encoding="utf8" ?>
<patient xmlns="http://stackoverflow.com/example">
.....
</patient>
by using code like this:
Message MyRestMethod()
{
Patient patientObject = new Patient() {Name="Mickey Mouse"};
Message message = WebOperationContext.Current.CreateXmlResponse<Patient>(patientObject);
return message;
}
However sometimes, the web service is used by a web browser, and so it would be much nicer if it would return documents like this:
<?xml version="1.0" encoding="utf8" ?>
<?xml-stylesheet type="text/xsl" href="/stylesheet/format.xsl" ?>
<patient xmlns="http://stackoverflow.com/example">
.....
</patient>
I have done some substantial digging around, and can almost do it by deriving my own message and overiding OnWriteBodyContents() to get access to the XmlDictionaryWriter. At this point, I then discovered that WriteProcessingInstruction(name, text) not able to write xml-stylesheet instructions.
More importantly, WCF client code receiving an xml-stylesheet processing instruction also bombs out, so even if you "hack" the stream at the character level to add it, it would need not to be sent to WCF clients...
If anyone has a better suggestion, please let me know...
Having dome some substantial reading on this, the answer is that it is not sensible to add an xml-stylesheet marker in the XML being returned to the WCF client.
The markers are processing instructions, which instruct the interpreter to process the XML document in a certain way. In this particular case by applying an XSLT to the document. the WCF serialisation and deserialiser both reject XML with stylesheet processing instructions, which makes sense - as in the WCF client case you do not want the processing instruction to be followed.
However, for my usecase, having the stylesheet processing instruction in when the xml is returned to a browser does make sense, so I have solved my problem by doing a conditional serialisation based on the UserAgent in the request, and in the case of it not being the WCF client application, I am adding the stylesheet to the stream thats used to create the response message.
In such case you are most probably going to to custom message encoder because xml declaration is added by message encoder and it doesn't provide any features to add any other directives.
I am creating a WCF webservice with WcF Authentication Service and the first set of functions I need is to manage an inbox for a client. The client will be determined by the authentication.
This is my attempt at a RESTful design of the API:
https://api.mydomain.com/v1/inbox/messages (GET)
Returns a page of results in the inbox with an optional search filter applied
Count - number of records per page
Page - page to start on
Sort - (optional) field to sort on
Search - (optional) text to search for
https://api.mydomain.com/v1/inbox/mark (POST)
Marks one or more messages read or unread
Action - MarkRead or MarkUnread
MessageIDs - list of Message IDs to mark
https://api.mydomain.com/v1/inbox/archive (POST)
Archives one or more messages
MessageIDs - list of Message IDs to archive
Am I doing this right? If not, what would be a better way to design this interface?
Martin Fowler has a good summary of the Richardson Maturity Model and what it takes to make a RESTful service. Jan referenced one of Roy Fielding's posts, but there are some steps to take care of in addition to hypermedia (and HATEOAS).
With reference to the Richardson model, I think your API would need some changes to get to "Level 3" (duh duh duhhhh). The /v1/inbox/messages collection looks sound, and only supporting GET indicates that it's a read-only resource to the user. However POSTing actions and IDs to the /v1/inbox/mark and /v1/inbox/archive is only tunneling RPC-style services over HTTP - "Level 0" in the article.
I'd suggest something like the following as being a naive, non-hypermedia (i.e. "Level 2") API:
To retrieve a list of summary information of all of the messages (in all folders):
GET /v1/messages HTTP/1.1
Host: api.mydomain.com
Response:
content-type: text/xml
<?xml version="1.0"?>
<messages>
<message subject="Subject" unread="true" id="1234" folder="inbox" />
<message subject="Hello, world" unread="false" id="24" folder="inbox" />
...
</messages>
To retrieve a full message:
GET /v1/messages/1234 HTTP/1.1
Host: api.mydomain.com
Response:
content-type: text/xml
<?xml version="1.0"?>
<message subject="Subject" unread="true" id="1234" folder="inbox">
Hi, this is the message.
</message>
To edit a message (e.g. to mark it as read and move it to the archive folder):
POST /v1/inbox/messages/1234 HTTP/1.1
Host: api.mydomain.com
content-type: text/xml
<?xml version="1.0"?>
<message id="1234" unread="false" folder="archive" />
Note: here I'm intentionally using POST instead of PUT to indicate a partial update.
Other things that stand out as needing attention are:
Hypermedia responses and media types. Frankly this is better explained by others (e.g. the REST In Practice book, or the InfoQ Coffee Cup example by the same authors), but in short your responses should indicate to the client what other actions might be possible from the response to their most recent request, and allow them to discover the entire API from just a single URI. As an example, there is an implication of folders collections above. If GET /v1/messages/1234 returned:
<message subject="Subject" unread="true" id="1234" folder="inbox" >
Message text here.
<link rel="folder" href="http://api.mydomain.com/v1/folders/inbox" />
</message>
then the client would have a concrete example of a URI to try an OPTIONS on, and a good idea of what might be there.
Response codes and content: 200 OK is obvious. Respond with 403 Forbidden if the user is not authorized to view a particular message, 404 Not Found if the message ID doesn't exist. Every time you return an error, give the client some indication of how to correct their request (if at all possible).
Regarding to read/unread part
I do not think you need a post. I think you need put method
https://api.mydomain.com/v1/inbox/messageId/Read
https://api.mydomain.com/v1/inbox/messageId/Unread
Post needed when creating a new record and you want to update
For archive part I am agree. Just remember to return result for the archiving process.
Roy's POST is helpful when facing such questions: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Hence: focus on defining media type(s) instead of coupling your clients to predefined sets of URIs. They need not be registered, to be useful, BTW.
Maybe also see http://www.nordsc.com/ext/classification_of_http_based_apis.html#http-type-one
I think I have a pretty good grasp on the tenets of a RESTful architecture but I'm not there yet.
The part that I can't seem to figure out is how do the clients become aware of which HTTP methods are available to each resource? What about when a specific action is required in the application flow to continue a process?
Simplified Example:
Assuming a client places a simple order to my REST API.
The client will make a post request to: http://api.mycompany.com/orders
Request Payload
<order>
<items>
<sku>12345</sku>
<quantity>1</quantity>
</items>
</order>
Assuming the request is successful
Response Payload
<order>
<id>156</id>
<status>Pending Payment</status>
<items>
<sku>12345</sku>
<quantity>1</quantity>
</items>
<links>
<link rel="order" url="http://api.mycompany.com/orders/156" />
<link rel="invoice" url="http://api.mycompany.com/payments/156" />
<link rel="payment" url="http://api.mycompany.com/invoices/156" />
</links>
</order>
If I understand the hypermedia constraint correctly, I provide corresponding resources and the client can choose where to go from there.
In the above example the link with rel="order" could be a GET, PUT, or DELETE request. The link with rel="invoice" is restricted to a GET request. The link with rel="payment" will only accept a POST request.
How does the client know this? I know if they make an OPTIONS request to one of the aforementioned resources it should give them the methods that are available but I'm not sure if that's the standard way of handling this kind of scenario.
Any help would be greatly appreciated.
The simple fact is that those verbs will be documented in the documentation of the resources.
The question you didn't ask is, "How does a client know what the refs 'order', 'invoice', and 'payment' are for?".
Yet, they suffer the same problem you're asking. And they, too, need to be documented as well.
When those are documented, when those rels are explained as to what they are, why they exist, and what you as a resource consumer would use them for, then the actual verbs necessary to leverage those resources would be documented with them as well.
Clients can call any of the HTTP verbs on any URI you expose. Whether or not those actions will have any effect is a separate question.
Clients could discover which methods will work on a particular URI in different ways:
They call each URI with the different actions and dynamically figure out which ones work (returning a 2xx response code) and which ones return 405 - Method Not Allowed.
The client programmer reads your documentation and codes up the interactions ahead of time.
I'll be honest, I've never seen #1 implemented in a production system. #2 is what makes most sense to me and most humans that have to write clients that consume a REST API.
Note that there is more to consuming a REST API than just knowing which HTTP verb to use. The content and structure of the media type (for both requests and responses) is just as important to document and make available to those who plan to code against your system.