I have written a REST server based on RESTEasy.
In some of the resources, collections of objects are returned instead of single objects: the method that responds to the URL "/users/{user_id}" returns a single "user" object, but the method that responds to the URL "/users" returns all users. In the former case, I can include an HTTP header "Content-Location: URL" (although this is redundant since the caller has the correct URL). In the latter case, each item in the returned collection has its own location. I was thinking of added an XML attribute to each item specifying its location:
<users>
<user location="/users/1234">
...
</user>
<user location="/users/5678">
...
</user>
</users>
Is there some conventional way of returning this information?
This is a very common practice when designing hypermedia APIs. It is also highly recommended. There is no official "right" way of doing it, however one media type that has very explicit rules as to how you can do it is hal. See http://stateless.co/hal_specification.html
In hal your document would look like:
<resource href="/users">
<resource rel="item" href="/users/1234">
...
</resource>
<resource rel="item" href="/users/5678">
...
</resource>
</resource>
I picked the term "item" because it has been psuedo standardized, but you could put your own link relation, there are just a few rules you should follow when identifying your own link relations. (See RFC5988 for details)
Related
I'm using WsdlPull library to parse the WSDL file.
Is it possible to provide relative path in the schemaLocation whiling importing external XSD inside WSDL?
e.g.
<types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://myprovider/namespace1/namespace1" schemaLocation="schema1.xsd"/>
</schema>
</types>
Schemas should be resolved relative to the containing document (in this case the WSDL's Url), so this should work. In fact we have WSDL files that do exactly what you appear to be trying to do.
However the implementation is given quite a lot of freedom during the resolution process (for example allowing it to transform the url causing it to load from a cache rather than the actual url).
As your positing this I assume this is not working?
Given a SPARQL endpoint (which can be either SPARQL 1.0 or 1.1), say for example http://pt.dbpedia.org/sparql, how do I find which version of SPARQL it supports?
[One option is to try out a 1.1 feature such as aggregate functions and see it works but I guess there should be a better way to do this].
The SPARQL 1.1 Service Description specification says
SPARQL services made available via the SPARQL Protocol should return a
service description document at the service endpoint when dereferenced
using the HTTP GET operation without any query parameter strings
provided. This service description must be made available in an RDF
serialization, may be embedded in (X)HTML by way of RDFa [RDFA], and
should use content negotiation [CONNEG] if available in other RDF
representations
and further,
3.2.10 sd:supportedLanguage
Relates an instance of sd:Service to a SPARQL language (e.g. Query and Update) that it implements.
subPropertyOf: sd:feature domain: sd:Service range: sd:Language
3.3.3 sd:Language
An instance of sd:Language represents one of the SPARQL languages, including specific configurations providing
particular features or extensions. This document defines three
instances of sd:Language: sd:SPARQL10Query, sd:SPARQL11Query, and
sd:SPARQL11Update. type: rdfs:Class subClassOf: sd:Feature
But when I dereference most of the SPARQL endpoints, they just sends me an HTML SPARQL query editor.
UPDATE:
HTML editor issue was because I didn't use proper content negotiation on the endpoint. But now the question is there a good way to differentiate between a SPARQL 1.0 endpoint and a SPARQL 1.1 endpoint that doesn't provide a service description?
There are some work done on discovering and monitoring SPARQL endpoints such as SPARQL Web-Querying Infrastructure: Ready for Action?, Discoverability of SPARQL Endpoints in Linked Open Data but I didn't see a straight-forward way of finding the version.
The first thing that you should check is that when you're dereferencing the endpoint, you're asking for content in an RDF format, not the text/html, etc., that a web browser would specify by default, and that the endpoint isn't giving you certain outputs based on the user agent, etc. For instance, if you visit the DBpedia endpoint at http://dbpedia.org/sparql, you get an HTML query editor. However, if you request that page with the Accept header set to "application/rdf+xml", you'll get the service description. Without knowing what endpoints you're having trouble with, we can't really be much more help. This should work, but some endpoint doesn't do it, that's not really a technical problem that we can debug, especially if you don't tell us which endpoints you have problems with. Here's what this looks like using curl:
$ curl -H "Accept: application/rdf+xml" http://dbpedia.org/sparql
<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:sd="http://www.w3.org/ns/sparql-service-description#" >
<rdf:Description rdf:about="http://dbpedia.org/sparql">
<rdf:type rdf:resource="http://www.w3.org/ns/sparql-service-description#Service" />
<sd:endpoint rdf:resource="http://dbpedia.org/sparql" />
<sd:feature rdf:resource="http://www.w3.org/ns/sparql-service-description#UnionDefaultGraph" />
<sd:feature rdf:resource="http://www.w3.org/ns/sparql-service-description#DereferencesURIs" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/SPARQL_Results_JSON" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/SPARQL_Results_XML" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/Turtle" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/N-Triples" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/N3" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/RDF_XML" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/SPARQL_Results_CSV" />
<sd:resultFormat rdf:resource="http://www.w3.org/ns/formats/RDFa" />
<sd:supportedLanguage rdf:resource="http://www.w3.org/ns/sparql-service-description#SPARQL10Query" />
<sd:url rdf:resource="http://dbpedia.org/sparql" />
</rdf:Description>
Here's a live version that uses d3's XmlHttpRequest functionality. (I know you can do this without libraries, but I've been using a lot of d3 lately.)
/**
* Make a GET request to dbpedia.org/sparql
* and show the response in a PRE element.
*/
d3.xhr("http://dbpedia.org/sparql")
.get(function(error,data) {
console.log(error);
console.log(data);
d3.select("body")
.append("pre")
.text(data.response);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I have studied over the internet about restful APIs that it focuses on nouns not verbs in the url pattern, but now I am seeing multiple links that use verbs in the URL.
Here is an example.
POST /v1/payments/authorization/<Authorization-Id>/capture
POST /v1/payments/authorization/<Authorization-Id>/void
POST /v1/payments/authorization/<Authorization-Id>/reauthorize
this is Paypal apis. PayPal API
also on wikipedia on HTATEOAS page they gave a example ;
<?xml version="1.0"?>
<account>
<account_number>12345</account_number>
<balance currency="usd">100.00</balance>
<link rel="deposit" href="/account/12345/deposit" />
<link rel="withdraw" href="/account/12345/withdraw" />
<link rel="transfer" href="/account/12345/transfer" />
<link rel="close" href="/account/12345/close" />
</account>
link: Wiki HATEOAS
Can anyone help me get some clarity about this? why 'capture', 'void', 'deposit', 'withdraw', 'close' are in the URI cause they are all verbs not nouns?
or is this okay to use these kind of words in rest-full apis url?
Some snippets from the REST API Design Rulebook about different resource types:
Document
A document resource is a singular concept that is akin to an object instance or database
record.
Example:
http://api.soccer.restapi.org/leagues/seattle/teams/trebuchet
Collection
A collection resource is a server-managed directory of resources. Clients may propose
new resources to be added to a collection. However, it is up to the collection to choose
to create a new resource, or not.
Example: http://api.soccer.restapi.org/leagues/seattle/teams
Store
A store is a client-managed resource repository. A store resource lets an API client put
resources in, get them back out, and decide when to delete them. On their own, stores
do not create new resources; therefore a store never generates new URIs. Instead, each
stored resource has a URI that was chosen by a client when it was initially put into the
store.
Example: PUT /users/1234/favorites/alonso
Controller
A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.
Like a traditional web application’s use of HTML forms, a REST API relies on controller
resources to perform application-specific actions that cannot be logically mapped to
one of the standard methods (create, retrieve, update, and delete, also known as
CRUD).
Controller names typically appear as the last segment in a URI path, with no child
resources to follow them in the hierarchy.
Example: POST /alerts/245743/resend
Based on the definitions in the book, the URIs you've posted probably fall under the Controller resource type, of which the book later states:
Rule: A verb or verb phrase should be used for controller names
Examples:
http://api.college.restapi.org/students/morgan/register
http://api.example.restapi.org/lists/4324/dedupe
http://api.ognom.restapi.org/dbs/reindex
http://api.build.restapi.org/qa/nightly/runTestSuite
Other naming rules, just for completeness
Rule: A singular noun should be used for document names
Rule: A plural noun should be used for collection names
Rule: A plural noun should be used for store names
The trick is to make it all nouns (or entities) that operate with the CRUD verbs.
So instead of;
POST /v1/payments/authorization/<Authorization-Id>/capture
POST /v1/payments/authorization/<Authorization-Id>/void
POST /v1/payments/authorization/<Authorization-Id>/reauthorize
Do this;
capture -> POST /v1/payments/authorization/
void -> DELETE /v1/payments/authorization/<Authorization-Id>
reauthorize -> delete first then capture again.
In REST, the verb is the HTTP method. In your example it is POST but it could also be GET, PUT, or DELETE.
The noun is the resource identified by the URL. In your example the "nouns" are /v1/payments/authorization/<Authorization-Id>/capture, etc.
As you can see, this is not really a noun since capture is a verb: capture a payment authorization. This is not RESTful since it is a command, a verb, not a thing, a noun.
A better way would be to model these commands as things like /v1/payments/authorization/<Authorization-Id>/capturecommand. This command would be a thing, a noun. It could have state, for example if it was successful, what was the result, etc.
There is a lot of code out there that claims to be RESTful and isn't.
I have defined my service on the WSDL file this way:
<wsdl:service name="guestbook">
<wsdl:port binding="tns:guestbookSOAP" name="guestbookSOAP">
<soap:address location="http://localhost:8080/soapguestbook"/>
</wsdl:port>
Still I am getting the following error message when running wsimport on it:
At least one WSDL with at least one service definition needs to be provided.
Is there anything else I need to add?
The problem in your case is that the definitions element is missing, which is like a root.
WSDL has a specific structure, for which the root element should be the DEFINITIONs, under it various other elements are present like types, messages, portType, binding, services etc.
The structure is like the below:
<definitions>
<types> data type definitions........ </types>
<message> definition of the data being communicated.... </message>
<portType> set of operations...... </portType>
<binding> protocol and data format specification.... </binding>
</definitions>
For the meaning of each WSDL element look into the link:
https://www.w3schools.com/xml/xml_wsdl.asp
What do these parameters do and what are they used for?
<service name="...">
<parameter name="wsdlPortType" value="..."/>
</service>
Also, if anyone can explain the parameters wsdlServicePort, wsdlTargetNamespace, and wsdlServiceElement, that would be appreciated.
Axis 1.4 User's Guide:
When you deploy a service in Axis, users may then access your
service's URL with a standard web browser and by appending "?WSDL" to
the end of the URL, they will obtain an automatically-generated WSDL
document which describes your service.
Experimental results suggest that Axis is able to use a combination of the .wsdd deployment descriptor file and compiled Java .class files to generate the corresponding .wsdl for a given service. It's interesting to note that, for example, if you have a public method with a Generics return type such as Map, your generated .wsdl file will not contain the return type - it will contain "xsd:anyType" instead. I believe this is due to type erasure on the compiled .class file.
Anyway, the service options in the Axis .wsdd file (the parameters I referenced in my question such as wsdlPortType, wsdlServicePort, and wsdlTargetNamespace) are related to the .wsdl specifications. This can be inferred from the names themselves since they all contain 'wsdl' in them, but I wanted an explanation of what these parameters mean and I was unable to find relevant Axis documentation. Here are my findings:
wsdlPortType (portType): basically like a Java interface. Contains one "operation" element for each method name. Each "operation" contains "input" and "output" elements that are basically your input parameters and return parameter of the Java method.
wsdlServicePort (wsdl:binding) Associated with the portType. I think of it as a description of how to transmit the parameters for the portType. The spec has this to say:
A binding description component provides a framework for indicating
binding details for a portType description component. Binding details
SHOULD be used to indicate how messages MUST be formatted when they
are sent to or from the service. They SHOULD also be used to indicate
the transport protocol to be used to send the messages. A given
binding description component MUST NOT indicate more than one
protocol.
wsdl:service: Has a reference in it to the wsdl port binding (the implementation of the portType).
target namespace: Pretty much what I thought it was (same as a namespace anywhere else). It applies to all of the wsdl:definitions components, so anything in the wsdl file basically (wsdl:portType, wsdl:service, etc). There are a couple other rules that you can find in the spec though.
Problem:
When using Service?wsdl, the generated wsdl may not have
the same targetNamespace, portType, service element name, or
service port name as the original wsdl. This problem has
been reported by users and is a TCK issue.
Solution:
Four optional parameters are added to the deploy.wsdd and
queried by the JavaProvider (wsdlTargetNamespace, wsdlServiceElement,
wsdlServicePort and wsdlPortType).
Here is an example deploy.wsdd with the new parameters.
<!-- Services from AddressBookService WSDL service -->
<service name="AddressBook" provider="java:RPC">
<parameter name="wsdlTargetNamespace" value="urn:AddressFetcher2"/>
<parameter name="wsdlServiceElement" value="AddressBookService"/>
<parameter name="wsdlServicePort" value="AddressBook"/>
<parameter name="className" value="samples.addr.AddressBookSOAPBindingSkeleton"/>
<parameter name="wsdlPortType" value="AddressBook"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
Source: http://mail-archives.apache.org/mod_mbox/axis-java-dev/200206.mbox/%3C20020621143740.41268.qmail#icarus.apache.org%3E