From 2f103b269e2e69263d7e63541162faec13d2d22a Mon Sep 17 00:00:00 2001 From: Priyanshu Nayan Date: Wed, 17 Feb 2021 12:04:13 +0530 Subject: [PATCH 1/4] analysis of heracles --- docs/doczrc.js | 2 +- .../conceptual-guides/analysis_heracles.md | 178 ++++++++++++++++++ docs/src/styles/global.css | 2 +- 3 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 docs/src/content/conceptual-guides/analysis_heracles.md diff --git a/docs/doczrc.js b/docs/doczrc.js index f0b27e4..1f8374d 100644 --- a/docs/doczrc.js +++ b/docs/doczrc.js @@ -5,7 +5,7 @@ export default { "Quickstart", {name: 'Tutorial', menu:['First Tutorial']}, {name: 'How To Guides', menu: ['First How to Guide']}, - {name: 'Conceptual Guides', menu: ['Conceptual Guide 1']}, + {name: 'Conceptual Guides', menu: ['Analysis of Heracles.ts']}, {name: 'Modules', menu: ['Hydra in Depth']}, {name: 'FAQ', menu: ['Some Questions']}, ], diff --git a/docs/src/content/conceptual-guides/analysis_heracles.md b/docs/src/content/conceptual-guides/analysis_heracles.md new file mode 100644 index 0000000..8ecfae6 --- /dev/null +++ b/docs/src/content/conceptual-guides/analysis_heracles.md @@ -0,0 +1,178 @@ +--- +name: Analysis of Heracles.ts +menu: Conceptual Guides +--- + +# Analysis of Heracles.ts + +HydraClient, known as Heracles.ts, is a generic client for Hydra-powered Web APIs. You can find the code at this repository [here](https://github.com/HydraCG/Heracles.ts). It is the reference implementation of a Hydra client in TypeScript. + +## Client Part in Hydra + +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 state of server 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 adept to changes. + +Index of Heracles.ts: + +- Enumerations +- Classes +- Interfaces +- Type Aliases +- Variables +- Functions +- Object Literals + +Enumerations define a set of named constants. For example, `CrawlingDirection` contains members named `backwards` and forwards `defining` possible partial collection view directions. Similarly, Level has members named `FullSupport` and `None` demonstrating Hypermedia support level. FullSupport=100 means exact support of response whereas None=0 means not a supported response. `LinksPolicy` defines various possible link policies. + +Classes are a blueprint from which objects are created. Classes used in Heracles.ts are: + +The `HydraClientFactory` class provides a factory of HydraClient, meaning HydraClient can be configured and created using this class. By default, JSON-LD hypermedia processor, bodyResourceIRITemplateExpansionStrategy and fetch components are used to initialise HydraClient. + +`BodyResourceIRITemplateExpansionStrategy` class provides a simple implementation of `IRITemplateExpansionStrategy` interface where an input resource is used to fill all the possible IRI Templates with values. + +An IRI template is a template literal and a set of mappings. + +The `MappingsBuilder` Class provides a builder for IRI template variable mapping values. `MappingsCollection` class is an IRI template variable mappings collection. + +While requesting for a resource one may construct a query that is known only to the client and that’s where Templated Resources come into picture. The TemplatedResource Class provides the base functionality for resources that has an expandable template. TemplatedLink Class provides a link that can have a URI template. Whereas TemplatedOperation class defines an abstract hydra operation that uses a URI template to point to the target of the request. + +The somehow related resources are grouped together in a collection. For eg: `OperationCollection` provides a collection of abstract hydra operations that can be filtered with relevant criteria. Similarly LinkCollection provides a collection of a link that describes another resource and that filtered with relevant criteria. This filtering capability is provided by the `FilterableCollection` Class. The `ResourceFilterableCollection` inherits this basic functionality from `FilterableCollection` Class. Similarly `LinksCollection` and `OperationsCollection` class inherits from the `ResourceFilterableCollection` Class. + +The collection can get large and the need of pagination might occur. In Hydra this is achieved via `PartialCollectionView` that may contain links to first, next, previous and last PartialCollectionView. The client will have to crawl through the `PartialCollectionView`. This in, Heracles.ts is achieved by `PartialCollectionCrawler` class. It provides capability of crawling through partial collection views. + +The API Documentation consists of all the valid state changes, but chances are that EntryPoint might be missing from the API Documentation. To rectify that Heracles.ts uses `EntryPointCorrectingGraphTransformer`. It tries to correct missing entry point in hydra:ApiDocumentation resource. + +Interfaces contain the abstract functions and types. A Class then implements the interface. Interfaces are for classes discussed above are `IApiDocumentation`, `IClass`, `ICollection`, `ICrawlingOptions`, `IHydraClient`, `ILink`, etc. + +Type Alias gives a semantic name to the types. It's an alias for a type. For Eg: `Literal` is type alias for union type of string, boolean and number. Similarly `HeaderMatcher` is a type alias for a function of type that takes in header as param and returns boolean. `Hypermedia` is a type alias for functions that take in context and returns Hypermedia Processor. + +Variable `dependentTypes` is an array of two strings which helps in checking whether a resource is Hydra independent. Likewise JSONLdContext contains the IRI http://www.w3.org/ns/json-ld#context. `RdfNamespace` as the name suggests contains the IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#. + +Several helper functions are used in Heracles.ts. `AddTo` adds an item to the collection. `discoverCollectionsFrom` function finds out collections from given hypermedia. The collection function is used to create mapping of a collection and initialises with default values. `isLink` functions checks whether is type is `hydra:Link` or `hydra:TemplatedLink`. `linksAndOperations` function creates mappings of template, variable, expects, returns, etc with target values. + +Object Literals like `hydra` are defined in `namespaces.ts` file it defines the core vocabulary terms. JSONLd Helper contains a `validKeys` method that returns all the valid keys. The `rdf` object defines useful RDF terms. The `rdfs` defined useful RDFS terms. + +Load on server and speed can be a limitation for the client. But in [python-hydra-agent](https://github.com/HTTP-APIs/python-hydra-agent) we are discussing mainly how to reduce the load on the server and fast querying from the client. For this we are using Redis to reduce load on the server and we implemented indexing (specially secondary/faceted indexing) of objects and their properties in Redis with a good querying mechanism which makes operations faster and efficient. + + +### Run Heracles.ts in Browser + +Create a project folder and navigate into it. + +Make sure you have `node.js` installed. If not, follow the instructions [here](https://nodejs.org/en/download/). + +Install typescript. +```bash +npm install -g typescript +``` + +Run +```bash +npm init --yes +``` + +Install `browserify`, `tsify` (to bundle JS files), and Heracles. + +```bash +npm install browserify tsify @hydra-cg/heracles.ts --save +``` + +Create a new file `main.ts` and Import Heracles and create a new Instance of the client. +```typescript +//main.ts +import HydraClientFactory from "@hydra-cg/heracles.ts"; + +let hydraClient = HydraClientFactory.configure().withDefaults().andCreate(); +``` + + +Now let's fetch a resource. Anything that can be dereferenced by an IRI can be considered as a resource. + +```typescript +//main.ts +const main = async () => { +const resource = await hydraClient.getResource("http://myapi/"); +// Do something with resource +} +main(); +``` + +The getResource method returns a HypermediaContainer. To keep things simple, use a Hydra-powered API provided by the server of this ecosystem. Installing and running `hydrus` is pretty straightforward. Follow the instructions [here](https://github.com/HTTP-APIs/hydrus). + +Once the server is up and running, its API can be used. To see the results, console the resource. + +```typescript +//main.ts +const main = async () => { +const resource = await hydraClient.getResource("http://localhost:8000/api/vocab"); +console.log('resource', resource); +} +main(); +``` + +To compile our code into ES2018, run in the terminal: + +```bash +tsc --init --target es2018 +``` + +To run npm packages in the browser, they need to be bundled. In the terminal run: + +```bash +browserify main.ts -p [ tsify --noImplicitAny ] > bundle.js +``` +To run `bundle.js` in the browser, create an HTML file index.html and include that script. +```html + + + + + + title + + +

Heracles.ts Demo

+ + + +``` +Open the file in the browser and in the console of dev tools you can see the response. It should look like this. + +```json +{ +"@context": { + "ApiDocumentation": "hydra:ApiDocumentation", + "description": "hydra:description", + "expectsHeader": "hydra:expectsHeader" + ... +}​ +"@id": "http://localhost:8080/api/vocab" +"@type": "ApiDocumentation" +"description": "API Documentation for the server side system" +… +​} +``` +The client can be customised by choosing which resource relations should be treated as links and exposed in the links property. By calling either + +- `.withAllLinks()` - treats all related resources as links + +- `.withAllHttpLinks()` - similar as above, but only HTTP(S) URLs will be considered + +- `.withSameRootLinks()` - only URLs from the same root of the requested resource will be considered + +- `.withStrictLinks()` - this is the default - only links exposed as hydra:link will be considered + +```typescript +let hydraClient = HydraClientFactory.configure().withDefaults().withAllLinks().andCreate(); +``` +By default, JSON-LD serialisation is used, any other serialisations of RDF can be used. This can be achieved by calling either of the functions : + +- `.with(component: IHypermediaProcessor)` - accepts a custom implementation of the IHypermediaProcessor interface + +- `.withFactory(method: HypermediaProcessorFactory)` - accepts a parameter factory method that will provide the instance as required. + + +Refs: +- [Hydra Specification](https://www.hydra-cg.com/spec/latest/core/) + + +- [Heracles.ts Documentation](https://github.com/HydraCG/Heracles.ts/tree/master/docs) \ No newline at end of file diff --git a/docs/src/styles/global.css b/docs/src/styles/global.css index 691a5c9..c32f0d7 100644 --- a/docs/src/styles/global.css +++ b/docs/src/styles/global.css @@ -1,5 +1,5 @@ @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"); -* { +html { font-family: "Roboto", sans-serif !important; } From ff38f5d0bb19b7432583814f3cc65f963c26a99d Mon Sep 17 00:00:00 2001 From: Priyanshu Nayan Date: Thu, 18 Feb 2021 22:07:18 +0530 Subject: [PATCH 2/4] IRI template guide --- .../content/conceptual-guides/ IriTemplate.md | 215 ++++++++++++++++++ .../conceptual-guides/analysis_heracles.md | 178 --------------- docs/src/content/conceptual-guides/first.md | 6 - 3 files changed, 215 insertions(+), 184 deletions(-) create mode 100644 docs/src/content/conceptual-guides/ IriTemplate.md delete mode 100644 docs/src/content/conceptual-guides/analysis_heracles.md delete mode 100644 docs/src/content/conceptual-guides/first.md diff --git a/docs/src/content/conceptual-guides/ IriTemplate.md b/docs/src/content/conceptual-guides/ IriTemplate.md new file mode 100644 index 0000000..6f5c8ad --- /dev/null +++ b/docs/src/content/conceptual-guides/ IriTemplate.md @@ -0,0 +1,215 @@ +--- +name: IriTemplate +menu: Conceptual Guides +--- + +# IriTemplate explained with an example + +>**Note**: *This article uses the term URI and IRI interchangebly, IRIs being genaralized form of URIs supporting Unicode. (For + more information see [rfc for URI](https://tools.ietf.org/html/rfc3986) and [rfc for IRI](https://www.ietf.org/rfc/rfc3987.txt))* + +IRI Templates provide an easy and elegant way to describe a range of IRIs with the help of variable expansion. +In the context of hypermedia driven APIs, IRI templates are particularly useful when the server can't construct a URI +by itself; only the client possesses the required information to construct desired IRI. + +Hydra provides the `IriTemplate` class that can be used to provide IRI templates to the smart clients, which can be used +by those clients to construct valid IRIs. As the title of this article suggests, we will use an example to explain the +working of `IriTemplate` in detail. + +### Example +``` +{ + "@context": "http://localhost:8080/serverapi/context.jsonld", + "@id": "https://tiles.openplanner.team/planet", + "@type": "Collection", + "search": { + "@type": "IriTemplate", + "template": "https://c.tile.openstreetmap.org/{z}/{x}/{y}.examplejsonld", + "variableRepresentation": "BasicRepresentation", + "mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "x", + "property": "tiles:longitudeTile", + "required": true + }, + { + "@type": "IriTemplateMapping", + "variable": "y", + "property": "tiles:latitudeTile", + "required": true + }, + { + "@type": "IriTemplateMapping", + "variable": "z", + "property": "tiles:zoomTile", + "required": true + } + ] + } +} +``` +You can find more details related to this example [here](https://github.com/HydraCG/Specifications/issues/171) + +As explained above, in tiled maps when we open a map the client-side code uses some formula(the formula may vary +according to the tile numbering convention used by the service provider) which uses latitude, longitude, and zoom +to get tile identifiers(here x and y). When it has the value of x and y to identify a tile, it makes a request to the +server for that individual tile. + +For example [https://c.tile.openstreetmap.org/15/22994/14232.png](https://c.tile.openstreetmap.org/15/22994/14232.png) will return the tile identified by x = 22994 and +y = 14232 with zoom 15. +For x = 22990 and y = 14232 and zoom = 15 the URI will be [https://c.tile.openstreetmap.org/15/22990/14232.png](https://c.tile.openstreetmap.org/15/22990/14232.png), +same way we can construct URIs for different combinations of X, Y and zoom. To represent such ranges of URIs we can use a URI template(IRI template) `https://c.tile.openstreetmap.org/{z}/{x}/{y}`. + +Such IRI templates can be put in use with the help of Hydra `IriTemplate` class. It consists of a literal `template` +and a set of mappings(`IriTemplateMapping`). `template` holds the IRI template, here `https://c.tile.openstreetmap.org/{z}/{x}/{y}.examplejsonld` and `IriTemplateMapping` maps variables in the `template` with properties and may specify whether the variable +is required or not. + +In the example above variables x, y and z maps to `tiles:longiudeTile`, `tiles:latitudeTile` and `tiles:zoomTile` respectively. And all these variables are specified as `required` to expand the IRI template and create a valid IRI. + +As the name suggests, `variableRepresenation` specifies how the IRI template will be expanded and serialized when +values of variables are provided. +As of now it can possibly have one of two values either `BasicRepresentation` or `ExplicitRepresentation`. +`BasicRepresentation` does not differentiate between literals and IRIs, it simple omits data-type and language +information of literals. While `ExplicitRepresentation` diffrentiates between literals and IRIs by surrounding +literals with double quotes(") and it also explicitly specifies language and data-type information of literals, +for more see detailed [example](http://www.hydra-cg.com/spec/latest/core/#ex-16-the-different-variable-representations). +The client side code might look like this +```js +var client = new HydraClient(); +var collection = client.get("/api/planet"); +if (colletion.search) { + var filter = {}; + for (let mapping of collection.search.mappings) { + filter[mapping.variable] = value of variable; # set value of x, y and z + } + + var query = urlTemplate + .parse(collection.search.template) + .expand(filter); # expand the IRI + var data = client.get(query); + for (var member of data.members) { + // do something with the _member_, i.e. display it + } +} +``` +With the help of all these, the Hydra enabled client can expand the IRI template with provided values of variables. If in the future the URI is changed from `https://c.tile.openstreetmap.org/{z}/{x}/{y}` to `https://c.tile.openstreetmap.org/{z}/{y}/{x}` +the client won't have any difficulty adjusting to it. The client will receive the following kind of response from the server +``` +{ + "@context": "http://localhost:8080/serverapi/context.jsonld", + "@id": "https://tiles.openplanner.team/planet", + "@type": "Collection", + "search": { + "@type": "IriTemplate", + "template": "https://c.tile.openstreetmap.org/{z}/{y}/{x}.examplejsonld", + "variableRepresentation": "BasicRepresentation", + "mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "x", + "property": "tiles:longitudeTile", + "required": true + }, + { + "@type": "IriTemplateMapping", + "variable": "y", + "property": "tiles:latitudeTile", + "required": true + }, + { + "@type": "IriTemplateMapping", + "variable": "z", + "property": "tiles:zoomTile", + "required": true + } + ] + } +} +``` +From the response data above and the client-side code given above, we can see that the client-side code won't require +any changes and keep functioning normally. For x = 22990 and y = 14232 and zoom = 15 the URI constructed by the client +will be [https://c.tile.openstreetmap.org/15/14232/22990.png](https://c.tile.openstreetmap.org/15/14232/22990.png). + +### Searching interface supported by hydrus +hydrus utilizes the above explained `IriTemplate` to provide a searching interface over the collection of items. +To every collection response, it attaches an IriTemplate. This `IriTemplate` has template mapping defined for all the properties of the objects contained by the collection. +For illustration the `IriTemplate` generated for DroneCollection(defined in our [flock-vocab](https://github.com/HTTP-APIs/hydra-flock-vocab)) is attached below. +```js +{ + "@type":"IriTemplate", + "mapping":[ + { + "@type":"IriTemplateMapping", + "property":"http://auto.schema.org/speed", + "required":false, + "variable":"DroneState[Speed]" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/geo", + "required":false, + "variable":"DroneState[Position]" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/Property", + "required":false, + "variable":"DroneState[Direction]" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/fuelCapacity", + "required":false, + "variable":"DroneState[Battery]" + }, + { + "@type":"IriTemplateMapping", + "property":"https://schema.org/status", + "required":false, + "variable":"DroneState[SensorStatus]" + }, + { + "@type":"IriTemplateMapping", + "property":"vocab:Drone", + "required":false, + "variable":"DroneState[DroneURI]" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/name", + "required":false, + "variable":"name" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/model", + "required":false, + "variable":"model" + }, + { + "@type":"IriTemplateMapping", + "property":"http://auto.schema.org/speed", + "required":false, + "variable":"MaxSpeed" + }, + { + "@type":"IriTemplateMapping", + "property":"http://schema.org/device", + "required":false, + "variable":"Sensor" + }], +"template":"http://localhost:8080/serverapi/DroneCollection{?DroneState[Speed], DroneState[Position], DroneState[Direction], DroneState[Battery], DroneState[SensorStatus], DroneState[DroneURI], name, model, MaxSpeed, Sensor}", +"variableRepresentation":"hydra:BasicRepresentation" +} +``` + +hydrus also provides support for searching over sub-properties of properties. Variable names of such properties are formed as ` MainProperty[subProperty]`. For example, to search for all the Drones going in some particular direction, a client can use the `DroneState[Direction]` variable. + +#### Further related reading + +* [URI Templates](https://tools.ietf.org/html/rfc6570) + +* [Hydra Templated Links](http://www.hydra-cg.com/spec/latest/core/#templated-links) + +* [Filtering or Searching use case of Hydra](https://github.com/HydraCG/Specifications/blob/master/drafts/use-cases/7.searching-events.md) diff --git a/docs/src/content/conceptual-guides/analysis_heracles.md b/docs/src/content/conceptual-guides/analysis_heracles.md deleted file mode 100644 index 8ecfae6..0000000 --- a/docs/src/content/conceptual-guides/analysis_heracles.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -name: Analysis of Heracles.ts -menu: Conceptual Guides ---- - -# Analysis of Heracles.ts - -HydraClient, known as Heracles.ts, is a generic client for Hydra-powered Web APIs. You can find the code at this repository [here](https://github.com/HydraCG/Heracles.ts). It is the reference implementation of a Hydra client in TypeScript. - -## Client Part in Hydra - -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 state of server 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 adept to changes. - -Index of Heracles.ts: - -- Enumerations -- Classes -- Interfaces -- Type Aliases -- Variables -- Functions -- Object Literals - -Enumerations define a set of named constants. For example, `CrawlingDirection` contains members named `backwards` and forwards `defining` possible partial collection view directions. Similarly, Level has members named `FullSupport` and `None` demonstrating Hypermedia support level. FullSupport=100 means exact support of response whereas None=0 means not a supported response. `LinksPolicy` defines various possible link policies. - -Classes are a blueprint from which objects are created. Classes used in Heracles.ts are: - -The `HydraClientFactory` class provides a factory of HydraClient, meaning HydraClient can be configured and created using this class. By default, JSON-LD hypermedia processor, bodyResourceIRITemplateExpansionStrategy and fetch components are used to initialise HydraClient. - -`BodyResourceIRITemplateExpansionStrategy` class provides a simple implementation of `IRITemplateExpansionStrategy` interface where an input resource is used to fill all the possible IRI Templates with values. - -An IRI template is a template literal and a set of mappings. - -The `MappingsBuilder` Class provides a builder for IRI template variable mapping values. `MappingsCollection` class is an IRI template variable mappings collection. - -While requesting for a resource one may construct a query that is known only to the client and that’s where Templated Resources come into picture. The TemplatedResource Class provides the base functionality for resources that has an expandable template. TemplatedLink Class provides a link that can have a URI template. Whereas TemplatedOperation class defines an abstract hydra operation that uses a URI template to point to the target of the request. - -The somehow related resources are grouped together in a collection. For eg: `OperationCollection` provides a collection of abstract hydra operations that can be filtered with relevant criteria. Similarly LinkCollection provides a collection of a link that describes another resource and that filtered with relevant criteria. This filtering capability is provided by the `FilterableCollection` Class. The `ResourceFilterableCollection` inherits this basic functionality from `FilterableCollection` Class. Similarly `LinksCollection` and `OperationsCollection` class inherits from the `ResourceFilterableCollection` Class. - -The collection can get large and the need of pagination might occur. In Hydra this is achieved via `PartialCollectionView` that may contain links to first, next, previous and last PartialCollectionView. The client will have to crawl through the `PartialCollectionView`. This in, Heracles.ts is achieved by `PartialCollectionCrawler` class. It provides capability of crawling through partial collection views. - -The API Documentation consists of all the valid state changes, but chances are that EntryPoint might be missing from the API Documentation. To rectify that Heracles.ts uses `EntryPointCorrectingGraphTransformer`. It tries to correct missing entry point in hydra:ApiDocumentation resource. - -Interfaces contain the abstract functions and types. A Class then implements the interface. Interfaces are for classes discussed above are `IApiDocumentation`, `IClass`, `ICollection`, `ICrawlingOptions`, `IHydraClient`, `ILink`, etc. - -Type Alias gives a semantic name to the types. It's an alias for a type. For Eg: `Literal` is type alias for union type of string, boolean and number. Similarly `HeaderMatcher` is a type alias for a function of type that takes in header as param and returns boolean. `Hypermedia` is a type alias for functions that take in context and returns Hypermedia Processor. - -Variable `dependentTypes` is an array of two strings which helps in checking whether a resource is Hydra independent. Likewise JSONLdContext contains the IRI http://www.w3.org/ns/json-ld#context. `RdfNamespace` as the name suggests contains the IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#. - -Several helper functions are used in Heracles.ts. `AddTo` adds an item to the collection. `discoverCollectionsFrom` function finds out collections from given hypermedia. The collection function is used to create mapping of a collection and initialises with default values. `isLink` functions checks whether is type is `hydra:Link` or `hydra:TemplatedLink`. `linksAndOperations` function creates mappings of template, variable, expects, returns, etc with target values. - -Object Literals like `hydra` are defined in `namespaces.ts` file it defines the core vocabulary terms. JSONLd Helper contains a `validKeys` method that returns all the valid keys. The `rdf` object defines useful RDF terms. The `rdfs` defined useful RDFS terms. - -Load on server and speed can be a limitation for the client. But in [python-hydra-agent](https://github.com/HTTP-APIs/python-hydra-agent) we are discussing mainly how to reduce the load on the server and fast querying from the client. For this we are using Redis to reduce load on the server and we implemented indexing (specially secondary/faceted indexing) of objects and their properties in Redis with a good querying mechanism which makes operations faster and efficient. - - -### Run Heracles.ts in Browser - -Create a project folder and navigate into it. - -Make sure you have `node.js` installed. If not, follow the instructions [here](https://nodejs.org/en/download/). - -Install typescript. -```bash -npm install -g typescript -``` - -Run -```bash -npm init --yes -``` - -Install `browserify`, `tsify` (to bundle JS files), and Heracles. - -```bash -npm install browserify tsify @hydra-cg/heracles.ts --save -``` - -Create a new file `main.ts` and Import Heracles and create a new Instance of the client. -```typescript -//main.ts -import HydraClientFactory from "@hydra-cg/heracles.ts"; - -let hydraClient = HydraClientFactory.configure().withDefaults().andCreate(); -``` - - -Now let's fetch a resource. Anything that can be dereferenced by an IRI can be considered as a resource. - -```typescript -//main.ts -const main = async () => { -const resource = await hydraClient.getResource("http://myapi/"); -// Do something with resource -} -main(); -``` - -The getResource method returns a HypermediaContainer. To keep things simple, use a Hydra-powered API provided by the server of this ecosystem. Installing and running `hydrus` is pretty straightforward. Follow the instructions [here](https://github.com/HTTP-APIs/hydrus). - -Once the server is up and running, its API can be used. To see the results, console the resource. - -```typescript -//main.ts -const main = async () => { -const resource = await hydraClient.getResource("http://localhost:8000/api/vocab"); -console.log('resource', resource); -} -main(); -``` - -To compile our code into ES2018, run in the terminal: - -```bash -tsc --init --target es2018 -``` - -To run npm packages in the browser, they need to be bundled. In the terminal run: - -```bash -browserify main.ts -p [ tsify --noImplicitAny ] > bundle.js -``` -To run `bundle.js` in the browser, create an HTML file index.html and include that script. -```html - - - - - - title - - -

Heracles.ts Demo

- - - -``` -Open the file in the browser and in the console of dev tools you can see the response. It should look like this. - -```json -{ -"@context": { - "ApiDocumentation": "hydra:ApiDocumentation", - "description": "hydra:description", - "expectsHeader": "hydra:expectsHeader" - ... -}​ -"@id": "http://localhost:8080/api/vocab" -"@type": "ApiDocumentation" -"description": "API Documentation for the server side system" -… -​} -``` -The client can be customised by choosing which resource relations should be treated as links and exposed in the links property. By calling either - -- `.withAllLinks()` - treats all related resources as links - -- `.withAllHttpLinks()` - similar as above, but only HTTP(S) URLs will be considered - -- `.withSameRootLinks()` - only URLs from the same root of the requested resource will be considered - -- `.withStrictLinks()` - this is the default - only links exposed as hydra:link will be considered - -```typescript -let hydraClient = HydraClientFactory.configure().withDefaults().withAllLinks().andCreate(); -``` -By default, JSON-LD serialisation is used, any other serialisations of RDF can be used. This can be achieved by calling either of the functions : - -- `.with(component: IHypermediaProcessor)` - accepts a custom implementation of the IHypermediaProcessor interface - -- `.withFactory(method: HypermediaProcessorFactory)` - accepts a parameter factory method that will provide the instance as required. - - -Refs: -- [Hydra Specification](https://www.hydra-cg.com/spec/latest/core/) - - -- [Heracles.ts Documentation](https://github.com/HydraCG/Heracles.ts/tree/master/docs) \ No newline at end of file diff --git a/docs/src/content/conceptual-guides/first.md b/docs/src/content/conceptual-guides/first.md deleted file mode 100644 index 0bc7f45..0000000 --- a/docs/src/content/conceptual-guides/first.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: Conceptual Guide 1 -menu: Conceptual Guides ---- - -# Some Random content From 8f1b95e3336cd1774cb03a86aa5985012511d0c8 Mon Sep 17 00:00:00 2001 From: Priyanshu Nayan Date: Thu, 18 Feb 2021 22:11:44 +0530 Subject: [PATCH 3/4] correct nav --- docs/doczrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doczrc.js b/docs/doczrc.js index 1f8374d..0a54324 100644 --- a/docs/doczrc.js +++ b/docs/doczrc.js @@ -5,7 +5,7 @@ export default { "Quickstart", {name: 'Tutorial', menu:['First Tutorial']}, {name: 'How To Guides', menu: ['First How to Guide']}, - {name: 'Conceptual Guides', menu: ['Analysis of Heracles.ts']}, + {name: 'Conceptual Guides', menu: ['IriTemplate']}, {name: 'Modules', menu: ['Hydra in Depth']}, {name: 'FAQ', menu: ['Some Questions']}, ], From 3d05a7803b36feac0713cdd0f89d4fa7c906cfee Mon Sep 17 00:00:00 2001 From: Priyanshu Nayan Date: Thu, 18 Feb 2021 22:20:01 +0530 Subject: [PATCH 4/4] syntax highlighing --- docs/doczrc.js | 2 +- docs/src/content/conceptual-guides/ IriTemplate.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/doczrc.js b/docs/doczrc.js index 0a54324..d8de2fb 100644 --- a/docs/doczrc.js +++ b/docs/doczrc.js @@ -5,7 +5,7 @@ export default { "Quickstart", {name: 'Tutorial', menu:['First Tutorial']}, {name: 'How To Guides', menu: ['First How to Guide']}, - {name: 'Conceptual Guides', menu: ['IriTemplate']}, + {name: 'Conceptual Guides', menu: ['IRI Templates in Hydra']}, {name: 'Modules', menu: ['Hydra in Depth']}, {name: 'FAQ', menu: ['Some Questions']}, ], diff --git a/docs/src/content/conceptual-guides/ IriTemplate.md b/docs/src/content/conceptual-guides/ IriTemplate.md index 6f5c8ad..d0014c1 100644 --- a/docs/src/content/conceptual-guides/ IriTemplate.md +++ b/docs/src/content/conceptual-guides/ IriTemplate.md @@ -1,5 +1,5 @@ --- -name: IriTemplate +name: IRI Templates in Hydra menu: Conceptual Guides --- @@ -17,7 +17,7 @@ by those clients to construct valid IRIs. As the title of this article suggests, working of `IriTemplate` in detail. ### Example -``` +```json { "@context": "http://localhost:8080/serverapi/context.jsonld", "@id": "https://tiles.openplanner.team/planet", @@ -95,7 +95,7 @@ if (colletion.search) { ``` With the help of all these, the Hydra enabled client can expand the IRI template with provided values of variables. If in the future the URI is changed from `https://c.tile.openstreetmap.org/{z}/{x}/{y}` to `https://c.tile.openstreetmap.org/{z}/{y}/{x}` the client won't have any difficulty adjusting to it. The client will receive the following kind of response from the server -``` +```json { "@context": "http://localhost:8080/serverapi/context.jsonld", "@id": "https://tiles.openplanner.team/planet",