Step 4: Run (Part 1)
Run Your Local Web Server
Open a terminal window.
Enter Your Client Credentials
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.
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_IDPEnter https://login.inrupt.com
2. Client ID:
read -s MY_SOLID_CLIENT_ID && export MY_SOLID_CLIENT_IDEnter your Client ID.
3. Client Secret:
read -s MY_SOLID_CLIENT_SECRET && export MY_SOLID_CLIENT_SECRETEnter your Client Secret.
4. Authentication Flow Method:
read -s MY_AUTH_FLOW && export MY_AUTH_FLOWEnter 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./gradlew bootRunYour Web service runs on http://localhost:8080 .
Test the Service
Open another terminal window. To test, call the various endpoints defined in the ExpenseController class:
/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_WEBIDUpon 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.
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" }'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/expense1Upon 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" }'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"
}<https://storage.inrupt.com/your-root-container/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 (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"
}<https://storage.inrupt.com/your-root-container/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> .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/expense2To 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/expense2The operation should error with a NotFoundException .
See also CRUD Module.
Last updated