# CRUD Module

Both [SolidSyncClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html) and [SolidClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html) provide methods for reading and writing resources to your Solid Pod; that is, performing create/read/update/delete (CRUD) operations. The resources can be RDF resources as well as [non-RDF resources](https://docs.inrupt.com/sdk/java-sdk/crud-rdf-data/modeling-rdf-data) (such as **`.jpg`**, **`.pdf`**, **`.txt`**, **`.json`** files).

## `SolidClient`

[`SolidClient`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html) is an asynchronous client for interacting with Solid resources.

```java
SolidClient client = SolidClient.getClient();
```

For an authenticated client, pass the authenticated [Session object](https://docs.inrupt.com/sdk/java-sdk/authentication) to the client:

```java
client.session(mySession);
```

See also:

* [Authentication](https://docs.inrupt.com/sdk/java-sdk/authentication)
* [Session Management](https://docs.inrupt.com/sdk/java-sdk/authentication/session-management)

### `.create()`

[`SolidClient.create()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html#create\(T\)) creates a new resource ([SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html), [SolidContainer](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidContainer.html), and [SolidNonRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidNonRDFSource.html)) at the specified location in your Pod.

For example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To save an **`Expense`** object to a Pod, pass the object to the method:

```java
client.create(newExpense).toCompletableFuture().join();
```

{% hint style="warning" %}

* If any container in the location path does not exist, the method creates the missing containers as well as the resource.
* If the resource already exists at the location, the operation errors with **`PreconditionFailedException`**. Use `.update()` instead.
  {% endhint %}

### `.read()`

[`SolidClient.read()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html#read\(java.net.URI,java.lang.Class\)) reads a resource from your Pod and map to a specified class.

For example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To read the **`Expense`** resource from a Pod, pass the resource’s identifier (i.e., its URI) and the class:

```java
Expense myExpense = client.read(
   URI.create("https://..."),
   Expense.class).toCompletableFuture().join();
```

### `.update()`

[`SolidClient.update()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html#update\(T\)) updates a resource in your Pod.

* If the resource does not exist at the location, creates a new resource.
* If the resource already exists at the location, overwrites the resource.

For example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To update (or create) an **`Expense`** resource in a Pod, pass the object to the method:

```java
// ... Modify the fetched expense
// myExpense.setXXX(...);
// myExpense.setYYY(...);

// Update the RDF resource at the location
// specified in the myExpense's identifier field.

Expense response = client.update(myExpense).toCompletableFuture().join();
```

### `.delete()`

[`SolidClient.delete()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html#delete\(T\)) deletes a resource from your Pod.

* You can specify the URL of the resource to delete:

  ```java
  client.delete(URI.create("https://...")).toCompletableFuture().join();
  ```

or

* You can pass the object to delete:

  For example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html).

  ```java
  client.delete(new Expense(URI.create("https://..."))).toCompletableFuture().join();
  ```

{% hint style="info" %}
To delete a SolidContainer, the SolidContainer must be empty.
{% endhint %}

## SolidSyncClient

[SolidSyncClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html) is a synchronous client for interacting with Solid resources.

```java
SolidSyncClient client = SolidSyncClient.getClient();
```

For an authenticated client, pass the authenticated [Session object](https://docs.inrupt.com/sdk/java-sdk/authentication) to the client:

```java
client.session(mySession);
```

### `.create()`

[`SolidSyncClient.create()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html#create\(T\)) creates a new resource ([SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html), [SolidContainer](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidContainer.html), and [SolidNonRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidNonRDFSource.html)) at the specified location in your Pod.

For example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To save an **`Expense`** object to a Pod, pass the object to the method:

```java
client.create(newExpense);
```

{% hint style="info" %}

* If any container in the location path does not exist, the method creates the missing containers as well as the resource.
* If the resource already exists at the location, the operation errors with `PreconditionFailedException`. Use .update() instead.
  {% endhint %}

### `.read()`

[`SolidSyncClient.read()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html#read\(java.net.URI,java.lang.Class\)) reads a resource from your Pod and map to a specified class.

or example, assume an **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To read the **`Expense`** resource from a Pod, pass the resource’s identifier (i.e., its URI) and the class:

```java
Expense myExpense = client.read(
   URI.create("https://..."),
   Expense.class);
```

### `.update()`

[`SolidSyncClient.update()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html#update\(T\)) updates a resource in your Pod.

* If the resource does not exist at the location, it creates a new resource.
* If the resource already exists at the location, it overwrites the resource.

For example, assume a **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html). To update (or create) an **`Expense`** resource in a Pod, pass the object to the method:

```java
// ... Modify the fetched expense
// myExpense.setXXX(...);
// myExpense.setYYY(...);

// Update the RDF resource at the location
// specified in the myExpense's identifier field.

Expense response = client.update(myExpense);
```

### `.delete()`

[`SolidSyncClient.delete()`](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html#delete\(T\)) deletes a resource from your Pod.

* You can specify the URL of the resource to delete:

  ```java
  client.delete(URI.create("https://..."));
  ```

or

* You can specify the object to delete:

  For example, assume a **`Expense`** class that extends [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html).

  ```java
  client.delete(new Expense(URI.create("https://...")));
  ```

{% hint style="info" %}
To delete a SolidContainer, the SolidContainer must be empty.
{% endhint %}

## Headers

You can use the resource class’ **`getHeaders()`** method to get the headers:

* [SolidRDFSource.getHeaders()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html#method.summary)
* [SolidContainer.getHeaders()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidContainer.html#method.summary)
* [SolidNonRDFSource.getHeaders()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidNonRDFSource.html#method.summary)

See also [#headers](#headers "mention").

Alternatively, you can also use the resource class’ **`getMetadata()`** methods:

* [SolidRDFSource.getMetadata()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html#getMetadata\(\))
* [SolidContainer.getMetadata()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidContainer.html#method.summary)
* [SolidNonRDFSource.getMetadata()](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidNonRDFSource.html#getMetadata\(\))

The **`getMetadata()`** methods return Solid-specific data (parsed into Java types) from a resource’s response headers. To access the complete set of response headers, use the **`getHeaders()`** method.
