Step 4: Run (Part 1)#

Run Your Local Web Server#

Open a terminal window.

Enter Your Client Credentials#

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

    Warning

    Safeguard your Client ID and Client Secret values. Do not share these with any third parties as anyone with your Client ID and Client Secret values can impersonate you and act fully on your behalf.

    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

Save an Expense object as a new RDF resource.

If a resource already exists, does not overwrite the resource.

/api/expenses/get

Reads an RDF resource and returns the content as an 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.

/api/expenses/delete

Deletes the RDF resource associated with the Expense.

/api/resource/get

Reads an RDF resource and returns the content as text/turtle MIME-type.

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/00000000-your-pod-identifier/"]

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

Create an Expense Record#

To create an expense record as an RDF resource on your Pod at https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230 315/expense1, issue the following curl command, substituting your Pod Root in the request body:

Important

The destination URL https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230315/expense1 must not exist.

If a resource exists at the URL, see Update the Expense RDF Resource to overwrite the resource instead.

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

Tip

If you encounter an HTTP 403 Forbidden error, double check that you have substituted your Pod’s root in the identifier.

Upon success, the operation should return the content of the resource, formatted in Turtle:

<https://storage.inrupt.com/00000000-your-pod-identifier/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> .

Read the Expense RDF Resource#

To read the content at https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230 315/expense1, map it to the Expense class and return it serialized as a JSON, issue the following curl command, substituting your Pod Root:

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

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

{"identifier":"https://storage.inrupt.com/00000000-your-pod-identifier/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"}

Update the Expense RDF Resource#

To update the content at https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230 315/expense1, issue the following curl command, substituting your Pod Root 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/00000000-your-pod-identifier/expenses/20230315/expense1",
      "merchantProvider": "Example Restaurant",
      "description": "Team Lunch",
      "expenseDate": "2023-03-15",
      "amount": 100,
      "currency": "USD",
      "category": "Travel & Entertainment" }'

Upon success, the operation should return the content of the updated resource, formatted in Turtle:

<https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230315/expense1>
     a                              <https://schema.org/Invoice> ;
     <https://schema.org/purchaseDate>
             "2023-03-15T00: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> .

Unlike the POST request to http://localhost:8080/api/expenses/create, the PUT request to http://localhost:8080/api/expenses/update either:

  • Updates an existing resource, or

  • Creates the resource if it does not already exists.

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

curl -X PUT http://localhost:8080/api/expenses/update \
   -H 'Content-type:application/json'  \
   -d '{
      "identifier": "https://storage.inrupt.com/00000000-your-pod-identifier/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 content of the newly created resource, formatted in Turtle:

<https://storage.inrupt.com/00000000-your-pod-identifier/expenses/20230315/expense2>
     a                              <https://schema.org/Invoice> ;
     <https://schema.org/purchaseDate>
             "2023-03-15T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
     <https://schema.org/category>  "Office Equipment & Supplies" ;
     <https://schema.org/description>
             "Monitor" ;
     <https://schema.org/priceCurrency>
             "USD" ;
     <https://schema.org/provider>  "Example Supply Store" ;
     <https://schema.org/totalPrice>
             "300"^^<http://www.w3.org/2001/XMLSchema#decimal> .

Delete the Expense RDF Resource#

To delete the resource from your Pod,

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

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/00000000-your-pod-identifier/expenses/20230315/expense2

The operation should return a 404 status:

{"timestamp":"2023-03-16T04:29:50.206+00:00","status":404,"error":"Not Found","path":"/api/expenses/get"}