Commit 3f6cb4f6 authored by Élodie Thiéblin's avatar Élodie Thiéblin
Browse files

[README] Update README

parent 63253ff59911
Pipeline #7551 failed with stages
in 6 minutes and 42 seconds
# cwclientlibjs - client library for CubicWeb's rqlcontroller
Javascript clone of the cwclientlib python library that wraps the
rqlcontroller API offered by the cubicweb-rqlcontroller cube.
Tests
------
Running the test suite requires nodejs, mocha and xhr2.
\ No newline at end of file
# cwclientlibjs - client library for CubicWeb's rqlcontroller
Javascript clone of the cwclientlib python library that wraps the rqlcontroller API offered by the cubicweb-rqlcontroller cube.
To read about the rql client, go to [Section Client.ts](#client.ts).
To read about the providers, go to [Section Providers.ts](#providers.ts).
## Client.ts
The [client](src/client.ts) namespace provides helpers to run RQL queries on a cubicweb instance with the rqlcontroller cube.
The class [CwRqlClient](src/client.ts#L690) implements the interface [RqlClient](src/client.ts#L644) and provides the following functions:
- **queryRows(query:string, params?:any)**: runs query on the cubicweb instance and returns the results as [RqlRows](src/client.ts#L553) in a Promise. This function calls transactionV1
- **queryBindings(query:string, params?)**: runs query on the cubicweb instance with and returns the results as [RqlSolutions](src/client.ts#L586) in a Promise. This function calls transactionV2
- **queryAndTransform(query:string, params?,viewId)**: Build the url corresponding to the query with a given viewId and returns the content in a Promise
- **transactionV1(queries)**: runs a set of queries with the rqlio/1.0 interface and returns the query results or throws an error if something went wrong
- **transactionV2(queries)**: runs a set of queries with the rqlio/2.0 interface and returns the query results as [RqlIoV2TransactionResponse](src/client.ts#L576)
A RqlClient relies on an HttpClient. Two implementations are available [CwSimpleHttpClient](src/client.ts#L332) and [CwSigningHttpClient](src/client.ts#L462).
[CwSimpleHttpClient](src/client.ts#L332) requires a baseUrl (the base url of a cubicweb instance). A boolean can be added to allow cross origin requests.
The CwSimpleHttpClient can perform a doLogin(login,password) operation on the cubicweb instance and perform the queries by using cookies (see [Known issues](#known-issues)).
It can also be transformed into a CwSigningHttpClient (toSigningClient()) after a doLogin() operation. It requires that the CubicWeb user has at least an enabled token linked to his/her account.
[CwSigningHttpClient](src/client.ts#L462) requires a baseUrl (the base url of a cubicweb instance), a tokenName, a tokenValue and a hashMethod code. Each request will contain a Authorization header with the connection token and its hashed value.
```javascript
import {providers, client} from '@logilab/cwclientlibjs';
// url is the base url of your cubicweb instance
const url = 'http://my-cubicweb-instance-base-url/';
const rqlClient = new client.CwRqlClient(
new client.CwSimpleHttpClient(url, true)
);
const query = 'Any X, Y WHERE X is BlogEntry, X entry_of Y';
rqlClient.queryRows(query).then(res => {
console.log(res); // [[123,1], [234, 2]]
});
rqlClient.queryBindings(query).then(res => {
console.log(res); // [{'X': 123, 'Y': 1}, {'X':234, 'Y':2}]
});
rqlClient.queryAndTransform(query, 'rdf').then(res => {
console.log(res); // equivalent to http://my-cubicweb-instance-base-url/view?rql=Any X, Y WHERE X is BlogEntry, X entry_of Y &vid=rdf
});
rqlClient.transactionV1([query]).then(res => {
console.log(res); // [[[123,1], [234, 2]]]
});
rqlClient.transactionV2([query]).then(res => {
console.log(res); // [{rows: [[123,1], [234, 2]], variables : ['X','Y']}]
});
```
## Providers.ts
The [provider](src/providers.ts) namespace provides two main objects: [EntitySchemaProvider](#entityschemaprovider) and [EntityProvider](#entityprovider).
### EntitySchemaProvider
A [RqlEntitySchemaProvider](src/providers.ts#L593) provides an interface to load a CubicWeb instance Schema.
A EntitySchemaProvider provides the following functions:
- **getAllRelationsFor(typeEid:number)**: Outputs two lists: relationsFrom and relationsTo relative to the CWEType referenced by typeEid
- **getEntitySchemaByName(typeName: string)**: Retrieves a CWEType (as EntitySchema) from its name
- **getEntitySchemaById(typeEid: number)** : Retrieves a CWEType (as EntitySchema) from its eid
- **getEntitySchemaFor(eid:number)** : Retrieves a CWEType (as EntitySchema) for a given instance number
- **load()**: Loads the Schema
An RqlEntitySchemaProvider can instantiate a [LocalStorageEntitySchemasLoader](src/providers.ts#L259) which will store the schema in the browser's window.localStorage, if given a 'storageKey' value.
Additionnaly, two functions: **isCacheUsable** and **onRetrieved** can be given to the RqlEntitySchemaProvider, they can be used to deal with schema versioning.
- **isCacheUsable** is called in a LocalStorageEntitySchemasLoader, it takes a `providers.Schema` as input and outputs a boolean Promise. If the promise is resolved with the value `true`, the schema will be loaded from the localStorage. Otherwise, if will be queried and loaded from the cubicweb instance again.
- **onRetrieved** is called after the schema has been queried and loaded from the cubicweb instance.
If no 'storageKey' value is given, a [RqlEntitySchemasLoader](src/providers.ts#L340) will be instantiated and the schema will be queried at every call of the `load` function.
```javascript
import {providers, client} from '@logilab/cwclientlibjs';
// url is the base url of your cubicweb instance
const url = 'http://my-cubicweb-instance-base-url/';
const rqlClient = new client.CwRqlClient(new client.CwSimpleHttpClient(url));
// Schema will not be cached
const schemaProvider = new providers.RqlEntitySchemaProvider(rqlClient);
// Schema will be cached
const schemaProviderWithLocalStorage = new providers.RqlEntitySchemaProvider(
rqlClient,
'mySchemaStorageKey'
);
// load a schema
schemaProvider.load().then((schema: providers.Schema) => {
console.log(schema);
});
// load a schema
schemaProviderWithLocalStorage.load().then((schema: providers.Schema) => {
console.log(schema);
});
```
A Schema is a json object with two entries:
- a **metadata** object which is computed on the schema load. At the moment, the metadata contains the schema loading timestamp.
- **entities**: a list of EntitySchema, each EntitySchema describes a CWEType, its attributes and to and from relations.
Example instanciation of a schema object:
```json
{
"metadata": {
"timestamp": "2020-04-20T09:35:49.183Z"
},
"entities": [
{
"eid": 30,
"name": "BlogEntry",
"modificationDate": "2009/09/01 12:15:04",
"specializes": null,
"attributes": [
{"eid": 78, "name": "title", "type": "String", "cardinality": 2}
],
"relationsTo": [
{
"eid": 6055,
"name": "entry_of",
"from": 30,
"fromName": "BlogEntry",
"fromCardinality": 1,
"to": 6044,
"toName": "Blog",
"toCardinality": 1,
"description": ""
}
],
"relationsFrom": [
{
"eid": 711,
"name": "tags",
"from": 61,
"fromName": "Tag",
"fromCardinality": 1,
"to": 30,
"toName": "BlogEntry",
"toCardinality": 1,
"description": "indicates that an entity is classified by a given tag"
}
]
}
]
}
```
### EntityProvider
Three entity Providers:
- [RqlEntityProvider](src/providers.ts#L682): Provides access to entities through a RQL enpoint. An EntitySchemaProvider can be specified on implementation, for example to cache the Schema in the localStorage.
- [EJsonExportEntityProvider](src/providers.ts#L812): Provides access to entities through the ejsonexport view of a RQL endpoint
- [CachedEntityProvider](src/providers.ts#L859): Caches the access to entities provided by another provider
Each EntityProvider provides the following functions:
- **getEntity(eid:number)**: Gets an entity given its eid
- **getEntityGivenSchema(eid:number, entitySchema: EntitySchema)**: Gets an entity given its expected entitySchema (CWEType, list of attributes, relations to and from)
- **getEntityTitleGivenSchema(eid: number, entitySchema EntitySchema)** : Gets the title for an entity, i.e., the value of the first attribute in the list of the entitySchema attributes.
```javascript
import {providers, client} from '@logilab/cwclientlibjs';
// url is the base url of your cubicweb instance
const url = 'http://my-cubicweb-instance-base-url/';
const rqlClient = new client.CwRqlClient(new client.CwSimpleHttpClient(url));
// Schema will not be cached
const schemaProvider = new providers.RqlEntitySchemaProvider(
rqlClient,
'storageKey'
);
const rqlEntityProvider = new providers.RqlEntityProvider(
rqlClient,
schemaProvider
);
const eJsonEntityProvider = new providers.EJsonExportEntityProvider(rqlClient);
const cachedEntityProvider = new providers.CachedEntityProvider(
rqlEntityProvider
);
cachedEntityProvider.getEntity(123456).then(entity => {
console.log(entity);
});
```
An entity will be a json object, whose keys are defined by its EntitySchema (CWEType)
```json
{
"@eid": 123456,
"@type": "BlogEntry",
"title": "Super Blog Post",
"entry_of_BlogEntry_Blog": [11111],
"tags_Tag_BlogEntry": [765432, 99999],
"modification_date": "2010/03/01 18:45:52"
}
```
## Tests
Running the test suite requires nodejs, mocha and xhr2.
## Known issues
There seems to be a problem with Cookie handling: in the [doRequestFetch function](src/client.ts#L107). The headers of the request seem to be empty for every response.
Therefore, the login functionality is broken for the moment as it requires to access the `Set-Cookie` fields of HTTP Responses.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment