# 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](/sdk/java-sdk/crud-rdf-data/modeling-rdf-data.md) (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](/sdk/java-sdk/authentication.md) to the client:

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

See also:

* [Authentication](/sdk/java-sdk/authentication.md)
* [Session Management](/sdk/java-sdk/authentication/session-management.md)

### `.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](/sdk/java-sdk/authentication.md) 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inrupt.com/sdk/java-sdk/crud-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
