@cubicweb/client
This library allows any JavaScript client to communicate with a CubicWeb instance running with the
API cube.
It replaces the cwclientlibjs
library.
The full documentation is available here.
Compatible with API cube version 0.15 only.
Installation
@cubicweb/client is available from NPM:
npm i @cubicweb/client
yarn add @cubicweb/client
Then make sure you have a CubicWeb instance running with the
API cube.
Usage
This library exposes a Client
class used to send requests to the API.
This class requires the URL to your CubicWeb instance API endpoint
(eg: https://example.com/api
).
const client = new Client("https://example.com/api");
⚠️ Real API routes include the API version in the URL (eg: v1
),
but it must not appear here. The API version number will be automatically set by the client.
For example, if you used https://example.com/api/v1/schema
to retrieve your instance schema,
simply pass https://example.com/api
to the client,
it will automatically add /v1
on each request.
Your client object can then be used to send requests to the API.
See the Client documentation for more information.
Example
The following example tries to log in a user then performs some operations on the instance.
client
.login("login", "password")
.then(() => {
client
.schema()
.then((schema) => {
console.log("Found the instance's schema:");
console.log(schema);
})
.catch((e) => {
console.error("There was an error while fetching the schema:");
console.error(e);
});
client
.execute("Any X Where X eid 5")
.then((resultSet) => {
console.log("RQL request was successul and returned:");
console.log(resultSet);
})
.catch((e) => {
console.error("There was an error processing the RQL request:");
console.error(e);
});
const transaction = new Transaction();
const insertQuery = new RQLQuery(`INSERT Person X: X name "test"`);
transaction.push(insertQuery);
transaction.push(
new RQLQuery(`INSERT Person X: X name "test"`, {
created_eid: insertQuery.cellRef(0, 0),
})
);
client
.executeTransaction(transaction)
.then((callbackResult) => {
console.log("Transaction was successful and the callback returned:");
console.log(callbackResult);
})
.catch((e) => {
console.error("There was an error processing the transaction:");
console.error(e);
});
})
.catch((e) => {
console.error("There was an error while loggin in the user:");
console.log(e);
});
CORS handling
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server
to indicate any origins (domain, scheme, or port) other than its own from which a browser
should permit loading resources. -
MDN Web Docs
If the client is running on a different server from your CubicWeb instance,
you must authorize the URL the client is running on as well as the Content-Type
header in your
CubicWeb instance's configuration.
Authentication
The API cube uses a cookie authentication method by default. When you call the login route, the cookie will be automatically created by the browser.
If the client is running on a different server from your CubicWeb instance,
make sure you setup CORS as described above.
For the login to work, you may also need to modify the cookie sent by the API cube to set
SameSite
to None
.
You can use other authenticators if needed. Here is an example relying on the
cubicweb-signedrequest
cube (v3.x):
import { Client } from "@cubicweb/client";
import { SignedRequestAuthenticator } from "@cubicweb/client/authenticators/SignedRequestAuthenticator";
const authenticator = new SignedRequetAuthenticator({
id: "<token-id>",
token: "<token>",
});
const client = new Client(API_URL, { authenticator });
You can also provide your own authenticator by implementing the Authenticator
interface:
import { Authenticator, Client } from "@cubicweb/client";
const client = new Client(API_URL, {
authenticator: {
authenticate(info, init) {
const headers = new Headers(init.headers);
headers.append("Authorization", `Basic Zm9vOmJhcg==`);
return { info, init: { ...init, headers } };
},
},
});
Using the Schema
This library provides CubicWeb schema abstraction classes. Three classes are available:
Schema
- Global handling of the schema.
Can be used to query entities and relations.EntitySchema
- Handling of a single entity type.
Can be used to query relations and metadata about the entity.RelationDefinitionSchema
- Handling of a single relation.
Can be used to retrieve associated entities and metadata the relation.
The Schema
class is created from the JSON schema returned by the API.
The Client.schema()
method takes care of this for you.
If your schema does not change often, it is recommended to export it using the following command
(replace <YOUR_INSTANCE_NAME>
by the name of your instance):
cubicweb-ctl export-schema -f json <YOUR_INSTANCE_NAME>
You can then manually create the Schema object by passing your JSON schema to its constructor.
const schema = client.schema();
const schema = new Schema(your_raw_json_schema);
EntitySchema
and RelationDefinitionSchema
objects should not be created manually.
These are returned when querying a Schema
object.
const entitySchema = schema.getEntity("YourEntityType");
const relationDefinitionSchema = schema.matchRelationDefinitions({
subject: "YourEntityType",
type: "YourRelationType"',
object: "YourEntityType2"
});
See the documentation for more information.
TypeScript support
Both the client and the schema abstraction classes expose TypeScript types.
You can type the Schema class using the TypeScript representation of your instance schema
to benefit from the strong type inference. You can generate this representation using the command
(replace <YOUR_INSTANCE_NAME>
by the name of your instance):
cubicweb-ctl export-schema -f typescript <YOUR_INSTANCE_NAME>
This command will generate a file schema.ts
containing the typings.
You can then include it in your project. When using this generated type,
the TS engine will be able to detect invalid entity types and relations.
⚠️ You cannot type the schema when using the client.schema()
method.
This is intended to prevent errors if the JSON schema changes and not the TS schema.
You must export both the JSON schema and TypeScript schema to use the typings.
const schema = new Schema<InstanceSchema["entities"], InstanceSchema["relations_definitions"]>(your_raw_json_schema);
const entity = schema.getEntity("InvalidEntityType");
const entity = schema.getEntity("ValidEntityType");
Contribute
All @cubicweb
libraries are in the cubicwebjs monorepo.
Please refer to the main README.
Get Help
Contact us on Matrix and check the roadmap on the CubicWeb Repository.