/
index.html
985 lines (857 loc) · 42.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
<!DOCTYPE html>
<html>
<head>
<title>Hydra Core Vocabulary</title>
<meta charset="utf-8">
<script type="text/javascript" src="https://www.w3.org/Tools/respec/respec-w3c-common" async class="remove"></script>
<script type="text/javascript" src="../../js/jsonld.js" class="remove"></script>
<script type="text/javascript" src="../../js/respec-w3c-extensions.js" class="remove"></script>
<script type="text/javascript" class="remove">
//<![CDATA[
var respecConfig = {
// extend the bibliography entries
localBiblio: localBibliography,
// specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
specStatus: "unofficial",
//publishDate: "2012-08-30",
copyrightStart: "2012",
additionalCopyrightHolders: 'Copyright © 2012-' + new Date().getFullYear() + ' the Contributors to the Hydra Core Vocabulary Specification, published by the <a href="http://www.w3.org/community/hydra/">Hydra W3C Community Group</a> under the <a href="http://www.w3.org/community/about/agreements/cla/">W3C Community Contributor License Agreement (CLA)</a>. A human-readable <a href="http://www.w3.org/community/about/agreements/cla-deed/">summary</a> is available.',
// the specification's short name, as in http://www.w3.org/TR/short-name/
shortName: "hydra",
subtitle: "A Vocabulary for Hypermedia-Driven Web APIs",
// if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
// and its maturity status
// previousPublishDate: "2012-08-30",
// previousMaturity: "FPWD",
// previousDiffURI: "http://www.w3.org/TR/2012/WD-json-ld-syntax-20120830/",
// diffTool: "http://www.aptest.com/standards/htmldiff/htmldiff.pl",
// if there a publicly available Editor's Draft, this is the link
edDraftURI: "http://www.hydra-cg.com/spec/latest/core/",
// if this is a LCWD, uncomment and set the end of its review period
// lcEnd: "2009-08-05",
issueBase: "https://github.com/lanthaler/hydra/issues/",
// if you want to have extra CSS, append them to this list
// it is recommended that the respec.css stylesheet be kept
// extraCSS: [],
// editors, add as many as you like
// only "name" is required
editors: [
{
name: "Markus Lanthaler",
url: "http://www.markus-lanthaler.com/",
company: "Google",
w3cid: 49179
}
],
// authors, add as many as you like.
// This is optional, uncomment if you have authors as well as editors.
// only "name" is required. Same format as editors.
authors: [
{ name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
company: "Google" }
],
// WG information
wg: "Hydra W3C Community Group",
wgURI: "http://www.hydra-cg.com/",
wgPublicList: "public-hydra",
// wgPatentURI: "http://www.w3.org/2004/01/pp-impl/??????/status",
maxTocLevel: 4,
postProcess: [ postProc ],
alternateFormats: [
// { uri: "diff-20120712.html", label: "diff to previous version" }
{ uri: "core.jsonld", label: "JSON-LD" },
{ uri: "core.ttl", label: "Turtle" },
]
};
//]]>
</script>
<style type="text/css">
html {
background-image: none !important;
}
.hlist {
border: 1px solid navy;
padding:5px;
background-color: #F4FFFF;
}
.hlist li {
display: inline;
display: inline-table;
list-style-type: none;
padding-right: 20px;
}
.highlight {
font-weight: bold;
color: #0a3;
}
.comment {
color: #999;
}
.illustration {
text-align: center;
}
#vocabulary-jsonld {
white-space: pre-wrap;
}
</style>
</head>
<body>
<section id="abstract">
<p>Hydra is a lightweight vocabulary to create hypermedia-driven Web APIs.
By specifying a number of concepts commonly used in Web APIs it enables
the creation of generic API clients.</p>
</section>
<section id="sotd">
<p class="issue">This entire document is a work in progress and several
sections are incomplete, missing, or outdated. All open issues and decisions
are documented in our
<a href="https://github.com/HydraCG/Specifications/issues">issue tracker</a>.
If you have questions, please don't hesitate to
<a href="http://www.hydra-cg.com/#community">join the Hydra W3C Community Group and post to the mailing list.</a>
</p>
<p>This specification was published by the
<a href="http://www.w3.org/community/hydra/">Hydra W3C Community Group</a>. It is
not a W3C Standard nor is it on the W3C Standards Track. Please note that under the
<a href="http://www.w3.org/community/about/agreements/cla/">W3C Community Contributor License Agreement (CLA)</a>
there is a limited opt-out and other conditions apply. Learn more about
<a href="http://www.w3.org/community/">W3C Community and Business Groups</a>.</p>
<p>To participate in the development of this specification, please join the
<a href="http://www.w3.org/community/hydra/">Hydra W3C Community Group</a>. If
you have questions, want to suggest a feature, or raise an issue, please send a mail to the
<a href="http://lists.w3.org/Archives/Public/public-hydra/">public-hydra@w3.org mailing list</a>.</p>
</section>
<section class="informative">
<h2>Introduction</h2>
<p>Coping with the ever-increasing amount of data becomes
increasingly challenging. To alleviate the information overload put on
people, systems are progressively being connected directly to each
other. They exchange, analyze, and manipulate humongous amounts of
data without any human interaction. Most current solutions, however,
do not exploit the whole potential of the architecture of the World
Wide Web and completely ignore the possibilities offered by Linked Data
technologies.</p>
<p>The combination of the REST architectural style and the Linked
Data principles offer opportunities to advance the Web of machines
in a similar way that hypertext did for the human Web. Most
building blocks exist already and are in place but they are rarely
used together. Hydra tries to fill that gap. It allows data to be
enriched with machine-readable affordances which enable
interaction. This not only addresses the problem that Linked Data
is still mostly read-only, but it also paves the way for a
completely new breed of interoperable Web APIs. The fact that it
enables the creation of composable contracts means that
interaction models of Web APIs can be reused at an unprecedented
granularity.</p>
</section>
<section>
<h2>Conformance</h2>
<p>This specification describes the conformance criteria for
<dfn data-lt="Hydra API documentation">Hydra API documentations</dfn>
and <dfn data-lt="Hydra client">Hydra clients</dfn>. These criteria are
relevant to authors, authoring tool implementers, and client
implementers. All authoring guidelines, diagrams, examples, and notes
in this specification are non-normative, as are all sections
explicitly marked as non-normative. Everything else in this
specification is normative.</p>
<p class="issue">Conformance for Hydra clients should probably not be
specified in this document.</p>
<p class="issue">Add normative statements</p>
<p>The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this
specification have the meaning defined in [[!RFC2119]].</p>
</section>
<section class="informative">
<h2>Hydra at a Glance</h2>
<p>The basic idea behind Hydra is to provide a vocabulary which enables a
server to advertise valid state transitions to a client. A client can
then use this information to construct HTTP requests which modify the
server’s state so that a certain desired goal is achieved. Since all
the information about the valid state transitions is exchanged in a
machine-processable way at runtime instead of being hardcoded into the
client at design time, clients can be decoupled from the server and
adapt to changes more easily.</p>
<p>The namespace of the Hydra core vocabulary is
<code>http://www.w3.org/ns/hydra/core#</code>, and the suggested prefix
is <code>hydra</code>. The figure below illustrates the vocabulary (the
figure’s goal is to show how Hydra is used rather than its precise
definition).</p>
<p class="issue">Is this illustration clear enough or is it confusing?
Feedback would be much appreciated.</p>
<div class="illustration">
<p><img src="vocabulary.png" alt="The Hydra core vocabulary" /></p>
<p class="caption">The Hydra core vocabulary</p>
</div>
<p class="issue">Add ranges for Operation "members"</p>
<p>An alphabetical index of the classes and properties of Hydra is
given below. All the terms are hyperlinked to their detailed
description for quick reference.</p>
<p id="vocabulary-overview"></p>
<p class="issue">The used prefixes should be documented somewhere.</p>
</section>
<section>
<h2>Using Hydra</h2>
<p>Throughout this section, a simple Web API featuring an issue tracker
will be used to illustrate how Hydra can be used. The Web API enables
its users to file new issues, modify or delete existing ones, and
to comment them. For the sake of simplicity, orthogonal aspects such
as authentication or authorization are not covered.</p>
<section>
<h3>Adding Affordances to Representations</h3>
<p>The exemplary Web API has to expose representations of issues and
comments. To enable interaction with those resources, a client has
to know which operations the server supports. In human-facing
websites such affordances are typically exposed by links and forms
and described in natural language. Unfortunately, machines can not
interpret such information easily. The solution that presents itself
is to reduce the language to a small number of unambiguous concepts
which are easily recognizable by a machine client. Hydra formalizes
such concepts.</p>
<p>The simplest and most important affordance on the Web are
hyperlinks. Without them, it would be impossible to browse the Web.
Users typically select the link based on the text it is labeled
with. To give machines a similar understanding, links can be
annotated with a link relation type—a registered token or a
URI identifying the semantics of the link. The following example
shows how such a typed link is used in HTML to reference a
stylesheet.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="A typed link referencing a stylesheet as used in HTML">
<!--
<link ****rel="stylesheet"**** href="http://www.example.com/styles.css" />
-->
</pre>
<p>In Linked Data, the link relation type corresponds to the property
itself. An example in JSON-LD would thus look as follows.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Referencing a stylesheet in JSON-LD">
<!--
{
****"urn:iana:link-relations:stylesheet"****: { "@id": "http://www.example.com/styles.css" }
}
-->
</pre>
<!-- <p class="note">The <code>urn:iana:link-relations:stylesheet</code> URN
is not officially registered (yet). For the moment, see
<a href="http://tools.ietf.org/html/draft-saintandre-iana-urn">draft-saintandre-iana-urn</a>
which defines this URN pattern.</p> -->
<p>Generally, a client decides whether to follow a link or not based on
the link relation (or property in the case of
Linked Data) which defines its semantics. There are however also
clients such as Web crawlers which simply follow every link
intended to be dereferenced. In HTML this usually means that all
links in anchor elements (the <code><a></code> tag) are
followed but most references in link elements (the
<code><link></code> tag), such as used in the example above,
are ignored. Since in RDF serializations no such distinction exists,
the best a client can do is to blindly try to dereference all URIs.
It would thus be beneficial to describe in a machine-readable manner
if a property represents a link intended to be
dereferenced or solely an identifier. Hydra's
<i>Link</i> class does just that. It can be used to define properties
that represent dereferenceable links. In the exemplary Web API used
throughout this section, it can be used to define a property
linking issues to their comments:</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Defining properties representing hyperlinks using Hydra's Link class">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/vocab#comments",
****"@type": "Link"****
}
-->
</pre>
<p>In the example above, a property identified with the URL
<code>http://api.example.com/vocab#comments</code> is defined to be
of the type <i>Link</i>. This is enough information for a client
understanding Hydra to know that the value of the
<code>comments</code> property in the following example is intended
to be dereferenced.</p>
<p class="note">It is recommended to dereference resources that are
within an API's domain. This may prevent possible issues with cross-site
scripting or obtaining resources which might have no meaning
to the client or such that the client would be unable to interpret.
Still, there is no formal prohibition of dereferencing resources
linked with well-known properties, e.g. <i>rdf:seeAlso</i>.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Using a property defined to be a hyperlink">
<!--
{
"@context": {
****"comments": "http://api.example.com/vocab#comments"****
},
"@id": "http://api.example.com/an-issue",
"title": "An exemplary issue linking to its comments",
****"comments": { "@id": "http://api.example.com/an-issue/comments" }****
}
-->
</pre>
<p>In the example above, the value of the <code>comments</code>
property is a JSON object with an <code>@id</code> member. This is
JSON-LD's convention to distinguish between strings and IRIs. By
using JSON-LD's type-coercion feature, the representation can be
made even more idiomatic:</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Using JSON-LD's type-coercion feature to create idiomatic representations">
<!--
{
"@context": {
"comments": { "@id": "http://api.example.com/vocab#comments", ****"@type": "@id"**** }
},
"@id": "http://api.example.com/an-issue",
"title": "An exemplary issue linking to its comments",
"comments": ****"http://api.example.com/an-issue/comments"****
}
-->
</pre>
<p>While links are enough to build read-only Web APIs, more powerful
affordances are required to build read-write Web APIs. Thus, Hydra
introduces the notion of operations. Simply speaking, an
<i>Operation</i> represents the information necessary for a client
to construct valid HTTP requests in order to manipulate the server's
resource state. As such, the only required property of an
<i>Operation</i> is its HTTP <i>method</i>. Optionally, it is
also possible to describe what information the server <i>expects</i>
or <i>returns</i>, including additional information about HTTP
status codes that might be returned. This helps a developer to
understand what to expect when invoking an operation. This
information has, however, not to be considered as being complete;
it is merely a hint. Developers should, e.g., expect that other
HTTP status codes might be returned and program their clients
accordingly.</p>
<p>The following example illustrates how representations can be
augmented with information that enables clients to interact with
them.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="A representation of an issue augmented with a delete operation">
<!--
{
****"@context": "http://www.w3.org/ns/hydra/context.jsonld"****,
"@id": "/an-issue",
"title": "An exemplary issue representation",
"description": "This issue can be deleted with an HTTP DELETE request",
****"operation"****: [
****{
"@type": "Operation",
"method": "DELETE"
}****
]
}
-->
</pre>
<p>The example above references Hydra's context to map properties such
as <code>operation</code> and <code>method</code> and values like
<code>Operation</code> to URLs that unambiguously
identify these concepts. It would be similarly valid JSON-LD if
these mappings would be directly embedded into the representation
or if the full URLs would be used instead. Typically, however, the
context is the same for a lot of representations in a Web API and
it thus makes sense to reduce the response size by leveraging a
remote context that can easily be cached by a client.</p>
</section>
<section>
<h3>Documenting a Web API</h3>
<p>In Web APIs, most representations are typically very similar.
Furthermore, resources often support the same operations. It thus
makes sense, to collect this information in a central documentation.
Traditionally, this has been done in natural language which forces
developers to hardcode that knowledge into their clients. Hydra
addresses this issue by making the documentation completely
machine-processable. The fact that all definitions can be identified
by URLs enables reuse at unprecedented granularity.</p>
<p>Hydra's <i>ApiDocumentation</i> class builds the foundation for
the description of a Web API. As shown in the following example,
Hydra describes a API by giving it a title, a short description, and
documenting its main entry point. Furthermore, the classes known to
be supported by the Web API and additional information about status
codes that might be returned can be documented. This information
may be used to automatically generate documentations in natural
language.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="The overall structure of a Hydra API documentation">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/",
****"@type": "ApiDocumentation"****,
****"title"****: ####"The name of the API"####,
****"description"****: ####"A short description of the API"####,
****"entrypoint"****: ####"URL of the API's main entry point"####,
****"supportedClass"****: [
####... Classes known to be supported by the Web API ...####
],
****"possibleStatus"****: [
####... Statuses that should be expected and handled properly ... ####
]
}
-->
</pre>
<p>In Linked Data, properties are, just as everything else, identified
by IRIs and thus have global scope which implies that they have
independent semantics. In contrast, properties in data models as
used in common programming languages are class-dependent. Their
semantics depend on the class they belong to. In data models classes
are typically described by the properties they expose whereas in
Linked Data properties define to which classes they belong. If no
class is specified, it is assumed that a property may apply to every
class.</p>
<p>These differences have interesting consequences. For example, the
commonly asked question of which properties can be applied to an
instance of a specific class can typically not be answered for
Linked Data. Strictly speaking, any property which is not explicitly
forbidden could be applied. This stems from the fact that Linked Data
works under an open-world assumption whereas data models used by
programmers typically work under a closed-world assumption. The
difference is that when a closed world is assumed, everything that
is not known to be true is false or vice-versa. With an open-world
assumption the failure to derive a fact does not automatically imply
the opposite; it embraces the fact that the knowledge is
incomplete.</p>
<p class="issue">Mention that Hydra classes are dereferenceable
resources.</p>
<p>Since Hydra uses classes to describe the information expected or
returned by an operation, it also defines a concept to describe the
properties known to be supported by a class. The following example
illustrates this feature. Instead of referencing properties directly,
<i>supportedProperty</i> references an intermediate data structure,
namely instances of the <i>SupportedProperty</i> class. This makes
it possible to define whether a specific property is required or
whether it is read-only or write-only depending on the class it is
associated with.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Defining a class and documenting its supported properties">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/#Comment",
****"@type": "Class"****,
****"title"****: ####"The name of the class"####,
****"description"****: ####"A short description of the class."####,
****"supportedProperty"****: [
####... Properties known to be supported by the class ...####
{
****"@type": "SupportedProperty"****,
****"property"****: "#property", ####// The property####
****"required"****: true, ####// Is the property required in a request to be valid?####
****"readable"****: false, ####// Can the client retrieve the property's value?####
****"writeable"****: true ####// Can the client change the property's value?####
}
]
}
-->
</pre>
<p>All instances of a specific class typically support the same
operations. Hydra therefore features a <i>supportedOperation</i>
property which defines the operations supported by all instances of
a class.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Defining a class and documenting its supported operations">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/#Comment",
"@type": "Class",
"title": ####"The name of the class"####,
"description": ####"A short description of the class."####,
"supportedProperty": [
####... Properties known to be supported by the class ...####
],
****"supportedOperation"****: [
####... Operations known to be supported by instances of the class ...####
]
}
-->
</pre>
<p>The same feature can be used to describe the operations supported
by values of a <i>Link</i> property. This is often helpful when
certain operations depend on the permissions of the current user. It
makes it, e.g., possible to show a "delete" link only if the current
user has the permission to delete the resource. Otherwise, the link
would simply be hidden in the representation.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Documenting the supported operations of link properties">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/#comments",
****"@type": "Link"****,
"title": "Comments",
"description": "A link to comments with an operation to create a new comment.",
****"supportedOperation"****: [
****{
"@type": "Operation",
"title": "Creates a new comment",
"method": "POST",
"expects": "http://api.example.com/doc/#Comment",
"returns": "http://api.example.com/doc/#Comment",
"possibleStatus": [****
####... Statuses that should be expected and handled properly ...####
****]
}****
]
}
-->
</pre>
<p>Keep in mind that operations specified in an <i>ApiDocumentation</i>
may fail at runtime as either resources or the <i>ApiDocumentation</i>
itself have changed since they have been retrieved. Also operation details
like <i>returns</i> or <i>possibleStatus</i> may vary at runtime,
which means client SHOULD verify received payloads at runtime.
A simple strategy to try to recover from such a situation is to reload
the <i>ApiDocumentation</i> and redo all pre-computations that were
based on the <i>ApiDocumentation</i> (or at least those that lead
to the current failure). Another, simpler approach would require
an application to show an error message with option to return
to a previous or home screen.</p>
<p class="issue">Describe the various properties of an operation.</p>
<p>Hydra also allows enriching both <i>ApiDocumentation</i> and
hypermedia controls with human-readable descriptions by applying
<i>title</i> and <i>description</i> (as shown in the examples above).
The former states a name of such a decorated element that could
be displayed as a label. The latter provides its description
to be presented i.e. as a hint.</p>
<p>Aforementioned <i>title</i> and <i>description</i> SHOULD take precedence
over standard <i>rdfs:label</i> and <i>rdfs:comment</i>.</p>
</section>
<section>
<h3>Discovering a Hydra-powered Web API</h3>
<p>The first step when trying to access a Web API is to find an entry
point. Typically, this is done by looking for documentation on the
API publisher's homepage. Hydra enables the API's main entry point
to be discovered automatically if the API publisher marks his
responses with a special HTTP Link Header as defined in [[RFC5988]].
A Hydra client would look for a Link Header with a relation type
<code>http://www.w3.org/ns/hydra/core#apiDocumentation</code> (this is
the IRI identifying the <i>hydra:apiDocumentation</i> property).</p>
<p>In the following example, a Hydra client simply accesses the
homepage of an API publisher (<code>http://www.example.com</code>)
to find the entry point of its API. A client may use an HTTP GET or
HEAD request. The difference between the two is that the former may
return a message-body in the response whereas the latter will not;
otherwise they are identical.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Discovering Hydra API documentation documents">
<!--
HEAD / HTTP/1.1
Host: www.example.com
====================================
HTTP/1.1 200 OK
...
Content-Type: text/html; charset=utf-8
****Link: <http://api.example.com/doc/>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"****
-->
</pre>
<p>The response in the example above contains an HTTP Link Header
pointing to <code>http://api.example.com/doc/</code>.
Retrieving that resource, the client would obtain a
<a>Hydra API documentation</a> defining the API's main entry
point:</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Retrieving a Hydra API documentation to obtain the main entry point">
<!--
GET /doc/ HTTP/1.1
Host: api.example.com
Accept: application/ld+json
====================================
HTTP/1.1 200 OK
...
Content-Type: application/ld+json
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/",
"title": "The example.com API",
****"entrypoint": "http://api.example.com/"****,
...
}
-->
</pre>
<p>Please note that in most cases the entry point will already be
known to the client. Thus, the discovery of the API documentation
using HTTP Link Headers is typically not necessary as the concepts
used in responses from the API will dereference to their
documentation.</p>
</section>
</section>
<section>
<h2>Advanced Concepts</h2>
<p class="issue">Describe Hydra's Resource class? Or should that better be
described somewhere in the beginning?</p>
<section>
<h3>Collections</h3>
<p>In many situations, it makes sense to expose resources that reference
a set of somehow related resources. Results of a search query or
entries of an address book are just two examples. To simplify such
use cases, Hydra defines the two classes <i>hydra:Collection</i> and
<i>hydra:PartialCollectionView</i>.</p>
<p>A <i>hydra:Collection</i> can be used to reference a set of resources
as follows:</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Referencing related resources using a Hydra Collection">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/an-issue/comments",
****"@type": "Collection"****,
****"totalItems": "4980"****,
****"member"****: [
{
"@id": "/comments/429"
},
{
"@id": "/comments/781",
"title": "Properties may be embedded directly in the collection"
},
...
]
}
-->
</pre>
<p>As shown in the example above, member items can either consist of
solely a link or also include some properties. In some cases embedding
member properties directly in the collection is beneficial as it may
reduce the number of HTTP requests necessary to get enough information
to process the result.</p>
<p>Since collections may become very large, Web APIs often chose to
split a collection into multiple pages. In Hydra, that can be achieved
with a <i>hydra:PartialCollectionView</i>. It describes a specific
view on the collection which represents only a subset of the collection's
members. A <i>PartialCollectionView</i> may contain links to the
<i>first</i>, <i>next</i>, <i>previous</i>, and <i>last</i>
<i>PartialCollectionView</i> which allows a client to find all members
of a <i>Collection</i>.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="A Hydra PartialCollectionView splits a collection into multiple views">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/an-issue/comments",
"@type": "Collection",
"totalItems": "4980",
"member": [
####... a subset of the members of the Collection ...####
],
****"view"****: {
"@id": "http://api.example.com/an-issue/comments?page=3",
****"@type": "PartialCollectionView"****,
****"first": "/an-issue/comments?page=1"****,
****"previous": "/an-issue/comments?page=2"****,
****"next": "/an-issue/comments?page=4"****,
****"last": "/an-issue/comments?page=498"****
}
}
-->
</pre>
<p class="issue">Say that all these properties are optional? What about
<i>first</i> and, perhaps more interestingly, <i>last</i>?</p>
</section>
<section>
<h3>Templated Links</h3>
<p>Sometimes, it is impossible for a server to construct a URL because
the URL depends on information only known by the client. A typical
use case are URLs which enable a client to query the server. In such
a case, the server cannot construct the URL because it does not know
the query the client is interested in. What the server can do however,
is to give the client a template to construct such a URL at runtime.
In Hydra, the <i>IriTemplate</i> class is used to do so.</p>
<p>An <i>IriTemplate</i> consists of a <i>template</i> literal and a set
of <i>mappings</i>. Each <i>IriTemplateMapping</i> maps a
<i>variable</i> used in the template to a <i>property</i> and may
optionally specify whether that variable is <i>required</i> or not.
The syntax of the template literal is specified by its datatype and
defaults to the [[!RFC6570]] URI Template syntax, which can be
explicitly indicated by <i>hydra:Rfc6570Template</i>.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Description of an IRI Template">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
****"@type": "IriTemplate"****,
****"template": "http://api.example.com/issues{?q}"****,
****"variableRepresentation": "BasicRepresentation"****,
****"mapping"****: [
{
****"@type": "IriTemplateMapping"****,
****"variable": "q"****,
****"property": "hydra:freetextQuery"****,
****"required": true****
}
]
}
-->
</pre>
<p>The example above maps the variable <code>q</code> to Hydra's
<i>freetextQuery</i> property and marks it as required.
As its name suggests, the <i>freetextQuery</i> property can be used
for free text queries.</p>
<p>A template syntax only details how to fill out simple string values,
but not how to derive such string values from typed values,
language-tagged strings, or IRIs. Hydra addresses this by
specifying how such values are to be serialized as strings. The
serialization of an <i>IriTemplate's</i> variables can be described
by setting the <i>variableRepresentation</i> property to
<i>BasicRepresentation</i> or <i>ExplicitRepresentation</i>. The
<i>BasicRepresentation</i> represents values by their lexical form. It
omits type and language information and does not differentiate between
IRIs and literals. The <i>ExplicitRepresentation</i>, on the other
hand, includes type and language information and differentiates
between IRIs and literals by serializing values as follows:</p>
<ul>
<li>IRIs are represented as-is.</li>
<li>Literals, i.e., (typed) values and language-tagged strings are
represented by their lexical form, surrounded by a single pair of
doubles quotes (<code>"</code>).</li>
<li>If a literal has a language, a single <code>@</code> symbol is
appended after the double-quoted lexical form, followed by a
non-empty [[BCP47]] language code.</li>
<li>If a literal has a type, two <em>caret</em> symbols
(<code>^^</code>) are appended after the double-quoted literal,
followed by the full datatype IRI.</li>
</ul>
<p>In both representations characters MUST NOT be escaped. In case the
representation format is not explicitly described, clients SHOULD
use the <i>BasicRepresentation</i> by default.</p>
<p class="warning">Although <i>ExplicitRepresentation</i> use of
<code>@</code> and <code>^^</code> is similar, it is <em>not</em> the
same as the [[Turtle]] representation for literals. Turtle literals
require escaping of special characters, surround datatype IRIs with
angular brackets (<code><</code> and <code>></code>), and also
allow single quotes (<code>'</code>) to indicate literals.
<i>ExplicitRepresentation</i> values must not be escaped, IRIs must
not be surrounded by any character, and only double quotes can
indicate literals.</p>
<p>Below are some example values serialized in the different
representations as well as the result of expanding the IRI template
<code>http://example.com/find/{value}</code> with the respective
value.</p>
<aside class="example nohighlight" title="The different variable representations">
<dl>
<dt>The IRI <code>http://www.hydra-cg.com/</code></dt>
<dd>BasicRepresentation: <code>http://www.hydra-cg.com/</code>; resulting IRI:
<code>http://example.com/find/http%3A%2F%2Fwww.hydra-cg.com%2F</code></dd>
<dd>ExplicitRepresentation: <code>http://www.hydra-cg.com/</code>; resulting IRI:
<code>http://example.com/find/http%3A%2F%2Fwww.hydra-cg.com%2F</code></dd>
<dt>The string <code>A simple string</code></dt>
<dd>BasicRepresentation: <code>A simple string</code>; resulting IRI:
<code>http://example.com/find/A%20simple%20string</code></dd>
<dd>ExplicitRepresentation: <code>"A simple string"</code>; resulting IRI:
<code>http://example.com/find/%22A%20simple%20string%22</code></dd>
<dt>The string <code>A string " with a quote</code></dt>
<dd>BasicRepresentation: <code>A string " with a quote</code>; resulting IRI:
<code>http://example.com/find/A%20string%20%22%20with%20a%20quote</code></dd>
<dd>ExplicitRepresentation: <code>"A string " with a quote"</code>; resulting IRI:
<code>http://example.com/find/%22A%20string%20%22%20with%20a%20quote%22</code></dd>
<dt>The language-tagged string <code>A simple string</code> with language English</dt>
<dd>BasicRepresentation: <code>A simple string</code>; resulting IRI:
<code>http://example.com/find/A%20simple%20string</code></dd>
<dd>ExplicitRepresentation: <code>"A simple string"@en</code>; resulting IRI:
<code>http://example.com/find/%22A%20simple%20string%22%40en</code></dd>
<dt>The decimal value <code>5.5</code></dt>
<dd>BasicRepresentation: <code>5.5</code>; resulting IRI: <code>http://example.com/find/5.5</code></dd>
<dd>ExplicitRepresentation: <code>"5.5"^^http://www.w3.org/2001/XMLSchema#decimal</code>; resulting IRI:
<code>http://example.com/find/%225.5%22%5E%5Ehttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23decimal</code></dd>
</dl>
</aside>
<p>Similar to how Hydra's <i>Link</i> class allows the definition of
properties that represent hyperlinks as described in
<a class="sectionRef" href="#adding-affordances-to-representations"></a>,
the <i>TemplatedLink</i> class allows the definition of properties
whose value are IRI templates. Hydra predefines one such property,
namely the <i>search</i> property which can be used to document
available search interfaces.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="The definition of Hydra's search property (extract)">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "****hydra:search****",
****"@type": "hydra:TemplatedLink"****
}
-->
</pre>
</section>
<section>
<h3>Description of HTTP Status Codes and Errors</h3>
<p>HTTP status codes have well defined semantics and can be used to
signal the outcome of an operation. Unfortunately, however, HTTP
status codes by themselves are often not specific enough, making it
difficult to understand the real cause of an error. For
instance, a <code>429 Too Many Requests</code> response is rarely
informative enough by itself. To address this issue, Hydra defines
a <i>Status</i> class which allows additional
information to be associated with an HTTP status code.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Associating additional information to an HTTP status code">
<!--
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@type": "****Status****",
****"possibleStatus": 429****,
"title": "Too Many Requests",
"description": "A maximum of 500 requests per hour and user is allowed.",
...
}
-->
</pre>
<p>An <i>ApiDocumentation</i> or an <i>Operation</i> may document the
status codes that might be returned by the server using the
<i>possibleStatus</i> property as described in
<a class="sectionRef" href="#documenting-a-web-api"></a>. This allows
a developer to understand what to expect when invoking an operation.
It has, however, not to be considered as an extensive list of all
potentially returned status codes; it is merely a hint. Developers
should expect to encounter other HTTP status codes as well.</p>
<p>A server may also return a <i>Status</i> directly in
a response. When doing so, it often makes sense to subclass the
<i>Status</i> to make its semantics more explicit.
Hydra defines just one such subclass, namely the <i>Error</i> class.
This provides an extensible framework to communicate error details to
a client.</p>
<pre class="example nohighlight" data-transform="updateExample"
title="Using Hydra's Error class to describe errors">
<!--
HTTP/1.1 400 Bad Request
Content-Type: application/ld+json
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@type": "****Error****",
"title": "An error occurred",
"description": "Typically, a specialization of this class is used in practice.",
...
}
-->
</pre>
</section>
</section>
<!-- <section>
<h2>Using Hydra Descriptions as JSON</h2>
<p class="issue">The are multiple ways to serialize a
<a>Hydra API documentation</a> in JSON-LD. To make it usable also for
plain-old JSON clients, the serialization has to have a deterministic
shape. The definition of a profile will make it possible to signal
or request specific serialization conventions at the media type
level. The definition of the profile might be as simple as defining
a JSON-LD frame.</p>
</section> -->
<section>
<h2>Classes</h2>
<div id="vocabulary-classes"></div>
</section>
<section>
<h2>Properties</h2>
<div id="vocabulary-properties"></div>
</section>
<section class="informative">
<h2>Acknowledgements</h2>
<p>The authors would like to thank the following individuals for contributing
their ideas and providing feedback for writing this specification:
Arnau Siches, elf Pavlik, Karol Szczepański, Mark Baker, Martijn Faassen,
Matthias Lehmann, Ruben Verborgh, Ryan J. McDonough, Sam Goto,
Thomas Hoppe, Tomasz Pluskiewicz, @wasabiwimp (on GitHub).</p>
</section>
<section class="appendix informative">
<h2>The Hydra Core Vocabulary in JSON-LD</h2>
<pre id="vocabulary-jsonld">
</pre>
</section>
</body>
</html>