I have a representation that contains a list of items. This could easily contain several hundred items.
<List>
<ListItem>...</ListItem>
<ListItem>...</ListItem>
...
<ListItem>...</ListItem>
<ListItem>...</ListItem>
</List>
For each item I want to provide a set of links that are available. Of the set of links, each item may only be allowed to access a subset of those links depending on some condition.
The following example demonstrates a brute force way of doing it.
<List>
<ListItem Id="345">
<Link rel="foo" href="http://example.org/List/Items/345/foo"/>
<Link rel="bar" href="http://example.org/List/Items/345/bar"/>
</ListItem>
<ListItem Id="346">
<Link rel="bar" href="http://example.org/List/Items/346/bar"/>
</ListItem>
<ListItem Id="347">
<Link rel="foo" href="http://example.org/List/Items/347/foo"/>
</ListItem>
...
</List>
Here is an alternative way
<List>
<ListItem Id="345" AvailableRels="foo bar"/>
<ListItem Id="346" AvailableRels="foo"/>
<ListItem Id="347" AvailableRels="bar"/>
...
<Link rel="foo" href="http://example.org/List/Items/{Id}/foo"/>
<Link rel="bar" href="http://example.org/List/Items/{Id}/bar"/>
</List>
The second approach looks much cleaner, it requires more intelligence on the client to deal with the URI template. The second is obviously much smaller to transfer over the wire, however, I am doing HTTP compression, so should I really care?
Thoughts? Are there other issues that I am missing? Is the AvailableRels idea a bit too non-standard? Is there anything like that in other media types?
If you're simply looking to reduce the size, consider including a 'self' link to the representation as a whole (which must be absolute), and declaring that all relative links are relative to it in your media type or protocol spec. (This is how Shoji does it) Then your example shrinks to:
<Link rel="self" href="http://example.org/List/Items/"/>
<List>
<ListItem Id="345">
<Link rel="foo" href="345/foo"/>
<Link rel="bar" href="345/bar"/>
</ListItem>
<ListItem Id="346">
<Link rel="bar" href="346/bar"/>
</ListItem>
<ListItem Id="347">
<Link rel="foo" href="347/foo"/>
</ListItem>
...
</List>
Both of these are in some new media type, so I guess that you get to define the processing models for both of these. The natural instinct is to go with the first one, since it doesn't add the invisible coupling between an attribute in one area of the XML and a URI template in some other place.
Prior art to guide us would be e.g. atompub or sun cloud API, both of which expose an enormous number of links, often repeating. I's just want to point out that OpenSearch could be handed as evidence for the URI template approach, since it exposes URI templates and special <Url> and <Query> elements that have element names matching the braces of the URI template. I personally consider OpenSearch templates very RESTful. Also plain HTML forms do something of the same, and can't not be considered RESTful in their base form.
The downside of providing URI templates is that you can't easily partition half of your items to have a href that goes to server A, and another that goes to server B, or that the different halves actually have different places. You're actually leaking something about the underlying data structure to your clients, and the clients therefore become dependent on all items having the same(ish) URI scheme for accessing foo or bar, making it all less flexible (perhaps depending on how you document the media type in question).
Looking at your representation I am finding very striking resemblance to Atom Syndication Format, which does this using atom:entry and atom:link. To be honest I am at an awe with Atom Syndication Format (ASF).
The RFC for ASF https://www.rfc-editor.org/rfc/rfc4287
The pagination of entries within ASF - rfc5005
If the RFCs are used your feed would look like -
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/" rel="self" />
<link href="http://example.org/before/345" rel="next" type="application/atom+xml" />
<link href="http://example.org/after/987" rel="previous" type="application/atom+xml"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>Darrel Miller</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Item 987</title>
<link href="http://example.org/List/Items/987/foo" rel="foo" />
<link href="http://example.org/List/Items/987/bar" rel="bar" />
<id>987</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
...
<entry>
<title>Item 345</title>
<link href="http://example.org/List/Items/345/foo" rel="foo" />
<id>345</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>
I suggest using this as would give power to the client to leverage standard clients to consume your representation. I personally prefer pagination in accordance with what mogsie mentioned above with ASF. Once pagination is in place I would suggest the standard HTTP stuff to improve performance:
Set HTTP Cache related headers in the response so that clients can use them to cache responses
Use a Cache server (Squid, Varnish) in front of the Application Server to reduce generating feed everytime.
Support compression, i.e., support both plain and compressed content depending on client capabilities.
What about just introducing pagination, if you're worried about raw resource size?
<List>
<Previous href="http://example.org/List/before/345"/>
<Next href="http://example.org/List/after/987"/>
<ListItem Id="345">
<Link rel="foo" href="http://example.org/List/Items/345/foo"/>
<Link rel="bar" href="http://example.org/List/Items/345/bar"/>
</ListItem>
...
<ListItem Id="987"> ... </ListItem>
<List>
Related
I would like to unambiguously describe (by using Wikidata URIs) what the subject matter of a blog post is using Schema.org.
Any pointers on how to do this?
You can use Schema.org’s about property:
The subject matter of the content.
While this property expects a Thing value, it’s possible to provide a URL value.
RDFa examples:
<article typeof="schema:BlogPosting">
<!-- URL value -->
<link property="schema:about" href="http://www.wikidata.org/entity/Q892" />
</article>
<article typeof="schema:BlogPosting">
<!-- Thing value -->
<div property="schema:about" typeof="schema:Person" resource="http://www.wikidata.org/entity/Q892">
<meta property="schema:name" content="J. R. R. Tolkien" />
</div>
</article>
We have a XML file that is on somewebsite and looks in a way like this (confidential parts stripped)
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="https://somewebsite.com/crm/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">Accounts</title>
<id></id>
<updated>2016-02-04T08:36:56Z</updated>
<link rel="self" title="Accounts" href="Accounts" />
<entry>
<title type="text"></title>
<updated>2016-02-04T08:36:56Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:Type>A</d:Type>
<d:UniqueTaxpayerReference m:null="true" />
<d:VATLiability m:null="true" />
<d:VATNumber m:null="true" />
<d:Website m:null="true" />
</m:properties>
</content>
</entry>
<link rel="next" href="https://somewebsite.com/Accounts?$skiptoken=guid'ee6bc390-a8ac-4bbd-8a4d-0a1f04ab9bd3'" />
</feed>
We use the new Rest connector to get the data out of this XML file.
The XML has pagination and every 60 entries you can load the next 60 with the link at the bottom of this xml file.
The problem i have is when, in the REST connector, we want to enable pagination with these setting:
Pagination Type: Next URL
Next URL field path:
/*[name()="feed"]/*[name()="link"][contains(#rel,"next")]/#href
It doesn't seem to work...
side note: the XML file has namespaces so i need to target the elements this way instead of /feed/link/...
I'm using Xpath syntax to target the link href, but maybe this is not the way to go? Or maybe the REST connector isn't using Xpath syntax?
Really hope someone can help me!
Actually it turns out that this seems to be due to a "bug" in the "Qlik REST Connector 1.0" so the pagination doesn't work.
But there is a fix for it:
1) Make sure that the Qlik REST Connector 1.0 connect dialog box has the NextUrl set to:
feed/link/attr:href
2) When the SQL has been generated after using the SELECT-button and going through the wizard you have to modify the sub-SELECT that reads like this:
.....
(SELECT
"attr:rel" AS "rel",
"attr:title" AS "title",
"attr:href" AS href,
"__FK_link"
FROM "link" FK "__FK_link"),
.....
On line 05 you will have to remove the text AS href.
So it should look like this:
.....
(SELECT
"attr:rel" AS "rel",
"attr:title" AS "title",
"attr:href",
"__FK_link"
FROM "link" FK "__FK_link"),
....
3) Find the LOAD statement that loads from this sub-select with a RESIDENT [MasterREST further down in the load script and make sure that the reference to href is changed to [attr:href] - or else you will get an error message while loading.
Should look like this after the change:
[link]:
LOAD [rel],
[title],
[attr:href],
[__FK_link] AS [__KEY_feed]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__FK_link]);
This worked for me:
/*[name()='feed']/*[name()='link'][#rel='next']/#href
Yours should also work actually, maybe whatever you are using does not agree with double quotes instead of single quotes.
I am trying to get an open search definition to work on subdomains.
I have added the correct line in the <head> of the html.
Example:
<link rel="search" type="application/opensearchdescription+xml" title="Example" href="http://www.example.org/opensearch.xml" />
In opensearch.xml:
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>Example</ShortName>
<LongName>Example Search</LongName>
<Description>Example Description</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16" type="image/x-icon">http://www.example.org/favicon.ico</Image>
<Url type="text/html" method="get" template="http://www.example.org/search/{searchTerms}" />
</OpenSearchDescription>
The search is correctly added to the omnibox settings in Google Chrome, when I visit http://www.example.org. The trigger keyword becomes "example.org".
However, when I visit http://subdomain.example.org, which has the same line in the <head>, the search is added with trigger keyword "subdomain.example.org" instead of "example.org".
Is there a way around this?
I have not found any information on how to set the trigger keyword in the documentation at http://www.opensearch.org/Specifications/OpenSearch/1.1 .
I have a DITA topic map that contains a subject scheme map that defines a taxonomy.
The topics in my topic map have been tagged with values from the taxonomy.
How can I render my topic map with facets to allow retrival of the topics, where the facets are the values from the subject scheme map?
John.
DITA 1.2 gives you the means to create a taxonomy or facet hierarchy -- the subjectScheme map -- and the means to apply the taxonomy or facet hierarchy to your DITA content -- the classification map.
To take advantage of that markup and implement a faceted-browsing experience, you need two things:
A processor that uses the subject classification values as it renders the output
A viewing application that implements faceted browsing
Currently, I am not aware of any DITA processors or viewing applications that do this.
Well, unless I'm misunderstanding the question, I assume you mean rendering to XHTML and that you want the facet metadata in the output for use in retrieval there by the end user? And I guess you want it in a meta tag then.
If so, I would do it like this:
For the sake of the example, I will assume that you have made a taxonomy that maps to the #product attribute.
First, in the stylesheet dita2htmlImpl.xsl, find the following template and copy it to your custom.xsl to override it (as an alternative you could do another override the get-meta template in get-meta.xsl, but it's so long...), and add a call to generateProductMetadata:
<xsl:template match="*" mode="chapterHead">
<head><xsl:value-of select="$newline"/>
<!-- initial meta information -->
<xsl:call-template name="generateCharset"/> <!-- Set the character set to UTF-8 -->
<xsl:call-template name="generateDefaultCopyright"/> <!-- Generate a default copyright, if needed -->
<xsl:call-template name="generateDefaultMeta"/> <!-- Standard meta for security, robots, etc -->
<xsl:call-template name="getMeta"/> <!-- Process metadata from topic prolog -->
<xsl:call-template name="copyright"/> <!-- Generate copyright, if specified manually -->
<xsl:call-template name="generateCssLinks"/> <!-- Generate links to CSS files -->
<xsl:call-template name="generateChapterTitle"/> <!-- Generate the <title> element -->
<xsl:call-template name="gen-user-head" /> <!-- include user's XSL HEAD processing here -->
<xsl:call-template name="gen-user-scripts" /> <!-- include user's XSL javascripts here -->
<xsl:call-template name="gen-user-styles" /> <!-- include user's XSL style element and content here -->
<xsl:call-template name="processHDF"/> <!-- Add user HDF file, if specified -->
<xsl:call-template name="generateProductMetadata"/> <!-- Add Product metadata -->
</head>
<xsl:value-of select="$newline"/>
</xsl:template>
Then, again in your custom.xml, add the template you called:
<xsl:template name="generateProductMetadata">
<meta name="product" content="{#product}"/>
<xsl:value-of select="$newline"/>
</xsl:template>
This gives me the following result in a test run:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="copyright" content="(C) Copyright 2005"/>
<meta name="DC.rights.owner" content="(C) Copyright 2005"/>
<meta name="DC.Type" content="topic"/>
<meta name="DC.Title" content="Technical data"/>
<meta name="DC.Relation" scheme="URI" content="18014398553839499_Technical_description.html"/>
<meta name="DC.Creator" content="Administrator"/>
<meta name="DC.Contributor" content="Administrator"/>
<meta name="DC.Date.Created" content="2013-03-05T11:13:04"/>
<meta name="DC.Date.Modified" content="2012-12-17T11:11:02"/>
<meta name="class" content="InfoType04"/>
<meta name="wf-state" content="NotReleased"/>
<meta name="DC.Format" content="XHTML"/>
<meta name="DC.Identifier" content="topic18014398553854475"/>
<meta name="DC.Language" content="en"/>
<link rel="stylesheet" type="text/css" href="commonltr.css"/>
<title>Technical data</title>
<meta name="product" content="product1"/>
</head>
Is that what you're looking for?
I'm using OpenRasta to create a Survey application.
I have a SurveyResource that is accessible at /surveys/{id} and editable at /surveys/{id}/edit
I'd now like to add questions to the survey, as that is the point of a survey, but I'm not sure what the most restful way of doing this is and how to set it up in OR.
I'm thinking I should have a QuestionResource (that has details of the question type, question text, etc) and it should be posted to /surveys/{id}/questions and handled by a question handler, but I can't work out how to configure OR.
I've pushed my project onto github at https://github.com/oharab/OpenSurvey/tree/add_question_to_survey
Can anyone help me?
Ben
it depends on the way you want to model your resources. It's perfectly possible that you'd never explicitly provide access to a single question, and would modify the entire survey document, like so:
PUT /surveys/123
<survey>
<link rel="update" href="/surveys/123" method="PUT"
type="application/vnd.mycorp.survey+xml" />
<question id="age">
<label>How old are you?</label>
<select>
<option>0 - 5</option>
<option>6 - 10</option>
<option>10 - 13</option>
</select>
</question>
</survey>
If you go this route, you could even use HTML, or HTML 5 for your content so it's easy to consume by clients. Now you're just modifying the entire survey document at once.
Alternatively, you might want to separately address each question, giving them an individual URI, which I think is what you're talking about, like so:
GET /survey/123
<survey>
<link rel="add-question" href="/survey/123/questions"
type="application/vnd.mycorp.surveyquestion+xml" method="POST" />
<question>
<link rel="delete" href="/questions/123-age" method="DELETE" />
<link rel="update" href="/questions/123-age" type="application/vnd.mycorp.surveyquestion+xml" method="PUT" />
<label>How old are you?</label>
<select>
<option>0 - 5</option>
<option>6 - 10</option>
<option>10 - 13</option>
</select>
</question>
</survey>
Neither of these is more RESTful than the other, the difference is only in granularity of call. If you need the granularity of the latter, then configure yourself a separate handler per resource as in
using(OpenRastaConfiguration.Manual)
{
ResourceSpace.Has.ResourcesOfType<Survey>().AtUri("/survey/{id}").HandledBy<SurveyHandler>();
ResourceSpace.Has.ResourcesOfType<Question>().AtUri("/questions/{id}").HandleBy<QuestionHandler>();
}