Step 4: Run (Part 1)

Run Your Local Web Server

Open a terminal window.

Enter Your Client Credentials

Export your registered client credentials (see the Prerequisites) as environment variables.

1. Identity Provider (the IDP with whom you registered your application):

read -s MY_SOLID_IDP && export MY_SOLID_IDP

Enter https://login.inrupt.com

2. Client ID:

read -s MY_SOLID_CLIENT_ID && export MY_SOLID_CLIENT_ID

Enter your Client ID.

3. Client Secret:

read -s MY_SOLID_CLIENT_SECRET && export MY_SOLID_CLIENT_SECRET

Enter your Client Secret.

4. Authentication Flow Method:

read -s MY_AUTH_FLOW && export MY_AUTH_FLOW

Enter client_secret_basic

Run the Application

Once you have entered your client credentials, start your application. From your project ( getting-started/ ) directory, run your Spring Boot application:

  • For Java, this tutorial assumes a Spring Boot Web Maven Project.

  • For Kotlin, this tutorial assumes a Spring Boot Web Gradle Project.

./mvnw spring-boot:run

Your Web service runs on http://localhost:8080 .

Reminder The application is running as you, the user who registered it.

Test the Service

Open another terminal window. To test, call the various endpoints defined in the ExpenseController class:

Endpoint
Description

/api/pods

Gets Pod URL(s) from the WebID Profile.

/api/expenses/create

Saves an Expense object as a new RDF resource. Returns the saved Expense object.

/api/expenses/get

Reads an RDF resource as an Expense object. Returns the Expense object.

/api/expenses/update

Saves an Expense object as an RDF resource.

  • If a resource already exists, overwrites the existing resource.

  • If no resource exists, creates a new resource.

Returns the saved Expense object.

/api/expenses/delete

Deletes an Expense resource (i.e., the RDF resource associated with the Expense).

For simplicity, the calls to the Web Server uses curl . However, you can access the endpoints from your front-end app as well.

Get Pod URL

To find your Pod URL, issue the following curl command, substituting your WebID (e.g., https://id.inrupt.com/yourUserName ):

curl -X GET http://localhost:8080/api/pods\?webid\=SUBSTITUTE_YOUR_WEBID

Upon success, the operation should return an array with your Pod Root URL; for example:

["https://storage.inrupt.com/your-root-container/"]

Since the application is running as you, it should have access to your Pod for the following CRUD operations.

Note In the following CRUD operations, substitue your-root-container with the value of your root container.

Create an Expense Record

To create an expense record as an RDF resource on your Pod at https://storage.inrupt.com/your-root-container/expenses/20230315/expense1 , issue the following curl command, substituting your root container in the request body:

curl -X POST http://localhost:8080/api/expenses/create \
   -H 'Content-type:application/json'  \
   -d '{
      "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense1",
      "merchantProvider": "Example Restaurant",
      "description": "Team Lunch",
      "expenseDate": "2023-03-06",
      "amount": 100,
      "currency": "USD",
      "category": "Travel & Entertainment" }'

Tip

  • If you encounter a ForbiddenException , double check that you have substituted your-root-container in the command.

  • If you encounter a PreconditionFailedException , check that the resource does not already exist at the the specified identifier. The .create() operation errors with PreconditionFailedException if a resource already exists.

Upon success, the operation returns the created Expense object:

{
    "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense1",
    "merchantProvider": "Example Restaurant",
    "expenseDate": "2023-03-06T00:00:00.000+00:00",
    "description": "Team Lunch",
    "amount": 100,
    "currency": "USD",
    "category": "Travel & Entertainment",
    "rdftype": "https://schema.org/Invoice"
}

For illustrative purposes, the server also prints out the content of the resource, formatted in Turtle:

<https://storage.inrupt.com/your-root-container/expenses/20230315/expense1>
        a                              <https://schema.org/Invoice> ;
        <https://schema.org/purchaseDate>  "2023-03-06T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
        <https://schema.org/category>  "Travel & Entertainment" ;
        <https://schema.org/description>
                "Team Lunch" ;
        <https://schema.org/priceCurrency>
                "USD" ;
        <https://schema.org/provider>  "Example Restaurant" ;
        <https://schema.org/totalPrice>
                "100"^^<http://www.w3.org/2001/XMLSchema#decimal> .

See also CRUD Module.

Read the Expense RDF Resource

To read the content at https://storage.inrupt.com/your-root-container/expenses/20230315/expense1 , map it to the Expense class and return it serialized as a JSON, issue the following curl command, substituting your your root container :

curl -X GET http://localhost:8080/api/expenses/get\?resourceURL\=https://storage.inrupt.com/your-root-container/expenses/20230315/expense1

Tip If you encounter an HTTP 403 Forbidden error, double check that you have substituted your-root-container in the command.

Upon success, the operation should return the contents as JSON:

{"identifier":"https://storage.inrupt.com/your-root-container/expenses/20230315/expense1","merchantProvider":"Example Restaurant","expenseDate":"2023-03-06T00:00:00.000+00:00","description":"Team Lunch","amount":100,"currency":"USD","category":"Travel & Entertainment","rdftype":"https://schema.org/Invoice"}

See also CRUD Module.

Update the Expense RDF Resource

To update the content at https://storage.inrupt.com/your-root-container/expenses/20230315/expense1 , issue the following curl command, substituting your your root container in the request body (the expenseDate field has changed):


curl -X PUT http://localhost:8080/api/expenses/update \
   -H 'Content-type:application/json'  \
   -d '{
      "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense1",
      "merchantProvider": "Example Restaurant",
      "description": "Team Lunch",
      "expenseDate": "2023-03-15",
      "amount": 100,
      "currency": "USD",
      "category": "Travel & Entertainment" }'

Tip If you encounter an HTTP 403 Forbidden error, double check that you have substituted your-root-container in the command.

Upon success, the operation should return the updated Expense object as JSON (as well as print out, on the server-side, the content formatted in Turtle):

{
    "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense1",
    "merchantProvider": "Example Restaurant",
    "expenseDate": "2023-03-15T00:00:00.000+00:00",
    "description": "Team Lunch",
    "amount": 100,
    "currency": "USD",
    "category": "Travel & Entertainment",
    "rdftype": "https://schema.org/Invoice"
}

Unlike the POST request to http://localhost:8080/api/expenses/create (which uses the .create() method), the PUT request to http://localhost:8080/api/expenses/update (which uses the .update() method) can either:

  • Update an existing resource, or

  • Create a new resource if it does not exists.

For example, issue the following PUT request to the api/expenses/update endpoint to create another expense resource, substitute your root container:

curl -X PUT http://localhost:8080/api/expenses/update \
   -H 'Content-type:application/json'  \
   -d '{
      "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense2",
      "merchantProvider": "Example Supply Store",
      "description": "Monitor",
      "expenseDate": "2023-03-15",
      "amount": 300,
      "currency": "USD",
      "category": "Office Equipment & Supplies" }'

Upon success, the operation should return the created Expense object as JSON (as well as print out, on the server-side, the content formatted in Turtle):

{
    "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense2",
    "merchantProvider": "Example Supply Store",
    "expenseDate": "2023-03-15T00:00:00.000+00:00",
    "description": "Monitor",
    "amount": 300,
    "currency": "USD",
    "category": "Office Equipment & Supplies",
    "rdftype": "https://schema.org/Invoice"
}

See also CRUD Module.

Delete the Expense RDF Resource

To delete the resource from your Pod, issue the following DELETE request, substituting your root container :

curl -X DELETE http://localhost:8080/api/expenses/delete\?resourceURL\=https://storage.inrupt.com/your-root-container/expenses/20230315/expense2

Tip If you encounter a ForbiddenException , double check that you have substituted your-root-container in the command.

To verify, issue a GET request to the http://localhost:8080/api/expenses/get endpoint:

curl -X GET http://localhost:8080/api/expenses/get\?resourceURL\=https://storage.inrupt.com/your-root-container/expenses/20230315/expense2

The operation should error with a NotFoundException .

See also CRUD Module.

Last updated