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 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.
Identity Provider (the IDP with whom you registered your application):
read -s MY_SOLID_IDP && export MY_SOLID_IDP
Enter
https://login.inrupt.com
Client ID:
read -s MY_SOLID_CLIENT_ID && export MY_SOLID_CLIENT_ID
Enter your Client ID.
Client Secret:
read -s MY_SOLID_CLIENT_SECRET && export MY_SOLID_CLIENT_SECRET
Enter your Client Secret.
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
./gradlew bootRun
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 |
---|---|
|
Gets Pod URL(s) from the WebID Profile. |
|
Saves an Expense object as a new RDF resource. Returns the saved Expense object. |
|
Reads an RDF resource as an Expense object. Returns the Expense object. |
|
Saves an Expense object as an RDF resource.
Returns the saved Expense object. |
|
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 substitutedyour-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 withPreconditionFailedException
if a resource already exists. To overwrite an existing resource, see Update the Expense RDF Resource.
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.
Read the Expense RDF Resource#
To read the content at
https://storage.inrupt.com/your-root-container/expenses/20230
315/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.
Update the Expense RDF Resource#
To update the content at
https://storage.inrupt.com/your-root-container/expenses/20230
315/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"
}
<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.
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.