This is the multi-page printable view of this section. Click here to print.
Introduction to SWS
1 - Introduction to SWS
SWS is a PeopleSoft module that understands your metadata and turns PeopleSoft data into clean REST APIs, ready for AI, modern applications, and partner integrations. Deploy production web services in under 5 minutes through configuration alone.
Welcome to the SWS product created by Cedar Hills Group, Inc.
- SWS is a PeopleSoft extension delivered as a standard Application Designer project that allows you to create web services with configuration only. We assume you read about it on the SWS Product Page.
- Check out the Your First SWS Service to see how fast you can create web services with configuration only.
- You should first read about SWS Concepts to get an understanding of how to think about SWS configuration and requests.
- Then you need to get SWS installed using the installation documentation
- Then read about the detailed SWS Configuration Options
- Not sure why you should use web services? I would check out the Why Use Web Services? chapter of our book.
When you install the SWS from Cedar Hills Group, it has two PeopleSoft web services that have very different use cases and audiences.
- SWS Get Services - You will use this method 95% of the time.
- PsoftQL Web Services
- This is a more advanced method to extract PeopleSoft data for a system integrator or outside vendor.
- You generally will NOT open up this web service to many users. This is geared toward internal integration tools like Mulesoft, Snaplogic, and Boomi.
Not sure which one fits your situation? See Which SWS Method Should I Use? for a visual decision flowchart covering both services and the SQL-vs-PsoftQL sub-choice inside a config.
SWS Get Services
The easiest and most secure way to expose your PeopleSoft data is by using SWS-configured web services. This method gives the PeopleSoft admin control over what data is exposed to third parties and is a more secure model for most use cases. You can read about how to set up a new web service in the SWS Configuration Section.
- A PeopleSoft power user
- Configures a new SWS configuration with either SQL or PsoftQL Syntax.
- Defines parameters and filters
- Grants security
- Give URL and Authentication information to the integration partner.
The integration partner ends up using a REST GET Service Operation called CHG_SWS. This web service checks security, resolves parameters, executes the SQL, encodes the data and returns it to the user.
- SWS Get Services - Standard HTTP Clients -
Service Operation: CHG_SWS- Most of the web services you configure with SWS will be set up to be used by non-trusted users.
- This is the default way to configure SWS services.
- You can start reading about how to set up a new web service in the SWS Configuration Section
(Advanced) PsoftQL Web Services
This is a more advanced method for a system integrator. You generally will NOT open up this web service to many users.
- PsoftQL Web Services -
Service Operation: CHG_SWS_PSOFTQL- This web service allows a highly trusted integration platform to request data in PsoftQL Syntax
- This is for internal integration tools like Mulesoft, Snaplogic and Boomi.
- When developing and prototyping new SWS configurations, your PeopleSoft admins may use this method to execute PsoftQL against PeopleSoft before configuring it in the most secure and locked-down SWS Get Service.
2 - Your First SWS Service
SWS combines two products. One product is advanced and caters to a specific group of users. The other has a broader application. In our first example, we’ll concentrate on the simplest method to create a web service. This involves crafting a SQL statement that can be exposed as a web service. This documentation will focus on the other areas of SWS. In this first example, we will focus on a quick win to expose a list of users and their emails.
Define Our Use Case
- In this use case, the objective is to provide a list of users with their names, employee IDs, and primary email addresses to an external system.
- Let’s further assume that the external system is going to have several other data requests that will be custom to this system/vendor. Therefore, we will “scope” our APIs to the vendor system in the URL path which will make more sense as we progress through this example. We will use “acmecorp” as the vendor name in our URL path.
- We also know from the vendor that they need specific field names in the output as they cannot handle data translation. Therefore, we will need to rename the fields in our output.
Create a SQL Statement
The first step is to create a SQL statement that will return the data we need. In this case, we will use the following SQL statement. This was generated by PS Query and copied out but you can do what magic SQL you want.
SELECT B.EMPLID, B.NAME, A.EMAIL_ADDR
FROM PS_EMAIL_ADDRESSES A, PS_PERSON_NAME B
WHERE A.PREF_EMAIL_FLAG = 'Y'
AND A.EMPLID = B.EMPLID
Create the SWS Service
- Navigate to: CHG Custom -> Simple Web Service Setup
- Use “Add Mode” to add a new value.
- Unique Identifier: This is auto-generated by SAVE.
- Description & Notes: Any Metadata you want to add to the service.
- URL Path: This is the URL path that will be used to access the service. In this case, we will use
acmecorpas the vendor name in our URL path. We further added/people/emailto have a full path of/acmecorp/people/email. This will be in the URL that the vendor will use to access the service. - Request Type: SQL
- SQL Statement: The SQL statement we created above.
- Output Fields: This is where we will rename the fields to match the vendor’s requirements. We will rename the fields to
UserID,LegalName, andPrimaryEmail. These fields were communicated by the vendor.

The second half of the page contains some miscellaneous options that we will not cover in this example. We will cover these in other examples. Leave the defaults.
Parameters: The parameters section does not need any values as the vendor will NOT pass in any parameters to filter or limit the data for this simple example.
Allowed Permission Lists: This is important and defines how users can access the system. We cover this in detail in the Security section. We granted the web service to our admin permission list and a new permission list we created just for ACME. We created a user to represent the ACME Corp server and the security structure looks like this:
- OPRID: ACMECORP_SWS_USER
- Password: phoebe-PROBABLE-dallas
- Role: ACMECORP_SWS_USER
- Permission List: ACMECORP_SWS_USER
- Web Service: CHG_SWS.CHG_SWG_GET
- Permission List: ACMECORP_SWS_USER
- OPRID: ACMECORP_SWS_USER

We can go to the last table and get the URL to test the service. We will use the URL in the next section. We give you HTTP and curl syntax.

I like HTTP Syntax as I think it is very clear. Let’s create our base64 encoded user name and password (Postman can do this for you) and ask for JSON accept: application/json. We will see if a response comes back. I am removing some of the data because we did not have a row limit specified and we have not implemented pagination which is possible but those are more advanced topics to cover later.
GET http://psft-cs-858.c.peoplesoftdemo-1470578694381.internal:8000/PSIGW/RESTListeningConnector/PSFT_CS/CHG_SWS/acmecorp/people/email
accept: application/json
authorization: Basic QUNNRUNPUlBfU1dTX1VTRVI6cGhvZWJlLVBST0JBQkxFLWRhbGxhcw==
HTTP/1.1 200 OK
connection: close
content-encoding: gzip
content-type: application/json; encoding=UTF-8
date: Thu, 21 Sep 2023 01:03:27 GMT
transfer-encoding: chunked
x-oracle-dms-ecid: 8458013e-3913-40bb-9698-190771ec7d9a-0000001f
x-oracle-dms-rid: 0
x-peoplesoftrequestid: ad31d07e-581a-11ee-a26c-7f8dcd811d6d
x-success: True
{
"data": [
{
"UserID": "FAI036",
"LegalName": "Shard Yahq",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FAEQT0001",
"LegalName": "Sandra Falix",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FAEQT0003",
"LegalName": "Ortega Pariara",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FAEQT0008",
"LegalName": "Rinda Marnar",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FAEQT0012",
"LegalName": "Judith Alkins",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FASS0150",
"LegalName": "Timothy Rond",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FASS0153",
"LegalName": "Tim Rihela",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FASS0154",
"LegalName": "Tona Ricado",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
},
{
"UserID": "FASSFAN001",
"LegalName": "Apple Fan",
"PrimaryEmail": "HCMGENUser1@ap6023fems.us.oracle.com"
}
],
"errors": "",
"meta": {
"rowCount": "4011",
"sqlIDExecuted": "d7fb7404-b1dc-4acd-b062-6d9f529f9b00",
"success": "True",
"debugMessages": "",
"QueryString": "NULL",
"URLPath": "acmecorp/people/email",
"finalSQL": "SELECT B.EMPLID, B.NAME, A.EMAIL_ADDR\n FROM PS_EMAIL_ADDRESSES A, PS_PERSON_NAME B\n WHERE A.PREF_EMAIL_FLAG = 'Y'\n AND A.EMPLID = B.EMPLID",
"productVersion": "2023-06-07",
"toolsVer": "8.58.07",
"currentUser": "ACMECORP_SWS_USER",
"responseDTTM": "2023-09-21 01:03:29.000000",
"psftTransactionId": "ad31d07e-581a-11ee-a26c-7f8dcd811d6d",
"dbname": "CS92U020",
"dbType": "ORACLE",
"serverTimeZone": "PST",
"ServerDirectory": "C:\\Users\\psoft\\psft\\pt\\8.58\\appserv\\APPDOM",
"debugMessage": ""
}
}
If you go back and look at the setup in the miscellaneous section we asked for metadata to be generated and we get back this JSON object which provides very helpful information for debugging.
"meta": {
"rowCount": "4011",
"sqlIDExecuted": "d7fb7404-b1dc-4acd-b062-6d9f529f9b00",
"success": "True",
"debugMessages": "",
"QueryString": "NULL",
"URLPath": "acmecorp/people/email",
"finalSQL": "SELECT B.EMPLID, B.NAME, A.EMAIL_ADDR\n FROM PS_EMAIL_ADDRESSES A, PS_PERSON_NAME B\n WHERE A.PREF_EMAIL_FLAG = 'Y'\n AND A.EMPLID = B.EMPLID",
"productVersion": "2023-06-07",
"toolsVer": "8.58.07",
"currentUser": "ACMECORP_SWS_USER",
"responseDTTM": "2023-09-21 01:03:29.000000",
"psftTransactionId": "ad31d07e-581a-11ee-a26c-7f8dcd811d6d",
"dbname": "CS92U020",
"dbType": "ORACLE",
"serverTimeZone": "PST",
"ServerDirectory": "C:\\Users\\psoft\\psft\\pt\\8.58\\appserv\\APPDOM",
"debugMessage": ""
}
Do you want XML instead? Simply change the accept header.
GET http://psft-cs-858.c.peoplesoftdemo-1470578694381.internal:8000/PSIGW/RESTListeningConnector/PSFT_CS/CHG_SWS/acmecorp/people/email
accept-encoding: gzip, deflate, br
accept: application/xml
authorization: Basic QUNNRUNPUlBfU1dTX1VTRVI6cGhvZWJlLVBST0JBQkxFLWRhbGxhcw==
user-agent: httpyac
HTTP/1.1 200 OK
connection: close
content-encoding: gzip
content-type: application/xml; encoding=UTF-8
date: Thu, 21 Sep 2023 01:16:11 GMT
transfer-encoding: chunked
x-oracle-dms-ecid: 8458013e-3913-40bb-9698-190771ec7d9a-00000020
x-oracle-dms-rid: 0
x-peoplesoftrequestid: 7343166f-581c-11ee-a26c-7f8dcd811d6d
x-success: True
<?xml version="1.0"?>
<response>
<data>
<row>
<UserID><![CDATA[FAI036]]></UserID>
<LegalName><![CDATA[Shard Yahq]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
<row>
<UserID><![CDATA[FAEQT0001]]></UserID>
<LegalName><![CDATA[Sandra Falix]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
<row>
<UserID><![CDATA[FAEQT0003]]></UserID>
<LegalName><![CDATA[Ortega Pariara]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
<row>
<UserID><![CDATA[FAEQT0008]]></UserID>
<LegalName><![CDATA[Rinda Marnar]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
<row>
<UserID><![CDATA[FAEQT0012]]></UserID>
<LegalName><![CDATA[Judith Alkins]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
<row>
<UserID><![CDATA[FASS0150]]></UserID>
<LegalName><![CDATA[Timothy Rond]]></LegalName>
<PrimaryEmail><![CDATA[HCMGENUser1@ap6023fems.us.oracle.com]]></PrimaryEmail>
</row>
</data>
<errors></errors>
<meta>
<rowCount>4011</rowCount>
<sqlIDExecuted>d7fb7404-b1dc-4acd-b062-6d9f529f9b00</sqlIDExecuted>
<peopleSoftRequestID>7343166f-581c-11ee-a26c-7f8dcd811d6d</peopleSoftRequestID>
<success>True</success>
<dbName>CS92U020</dbName>
<QueryString><![CDATA[NULL]]></QueryString>
<URLPath><![CDATA[acmecorp/people/email]]></URLPath>
<finalSQL><![CDATA[SELECT B.EMPLID, B.NAME, A.EMAIL_ADDR
FROM PS_EMAIL_ADDRESSES A, PS_PERSON_NAME B
WHERE A.PREF_EMAIL_FLAG = 'Y'
AND A.EMPLID = B.EMPLID]]></finalSQL>
<productVersion>2023-06-07</productVersion>
<peopleSoftUser>ACMECORP_SWS_USER</peopleSoftUser>
<peopleToolsVersion>8.58.07</peopleToolsVersion>
<requestTime>2023-09-21-01.16.11.000000</requestTime>
<debugMessage><![CDATA[]]></debugMessage>
</meta>
</response>
Or how about CSV? Just change the accept header. You will notice with CSV any metadata is in the header and the data is in the body. This is a common pattern with CSV.
GET http://psft-cs-858.c.peoplesoftdemo-1470578694381.internal:8000/PSIGW/RESTListeningConnector/PSFT_CS/CHG_SWS/acmecorp/people/email
accept-encoding: gzip, deflate, br
accept: text/csv
authorization: Basic QUNNRUNPUlBfU1dTX1VTRVI6cGhvZWJlLVBST0JBQkxFLWRhbGxhcw==
user-agent: httpyac
HTTP/1.1 200 OK
connection: close
content-encoding: gzip
content-type: text/csv; encoding=UTF-8
date: Thu, 21 Sep 2023 01:18:36 GMT
transfer-encoding: chunked
x-dbname: CS92U020
x-errors:
x-peoplesoftrequestid: ca315226-581c-11ee-a26c-7f8dcd811d6d
x-peoplesoftuser: ACMECORP_SWS_USER
x-peopletoolsversion: 8.58.07
x-productversion: 2023-06-07
x-requesttime: 2023-09-21-01.18.37.000000
x-rowcount: 4011
x-sqlidexecuted: d7fb7404-b1dc-4acd-b062-6d9f529f9b00
x-success: True
x-urlpath: acmecorp/people/email
"UserID","LegalName","PrimaryEmail"
"FAI036","Shard Yahq","HCMGENUser1@ap6023fems.us.oracle.com"
"FAEQT0001","Sandra Falix","HCMGENUser1@ap6023fems.us.oracle.com"
"FAEQT0003","Ortega Pariara","HCMGENUser1@ap6023fems.us.oracle.com"
"FAEQT0008","Rinda Marnar","HCMGENUser1@ap6023fems.us.oracle.com"
"FAEQT0012","Judith Alkins","HCMGENUser1@ap6023fems.us.oracle.com"
"FASS0150","Timothy Rond","HCMGENUser1@ap6023fems.us.oracle.com"
"FASS0153","Tim Rihela","HCMGENUser1@ap6023fems.us.oracle.com"
"FASS0154","Tona Ricado","HCMGENUser1@ap6023fems.us.oracle.com"
"FASSFAN001","Apple Fan","HCMGENUser1@ap6023fems.us.oracle.com"
"FASSFAN002","Honey Fan","HCMGENUser1@ap6023fems.us.oracle.com"
"FASSFAN003","Cookie Fan","HCMGENUser1@ap6023fems.us.oracle.com"
"FASSFAN004","Gavin Kravitz","HCMGENUser1@ap6023fems.us.oracle.com"
"FASSFAN005","KATHERINE HURADO","HCMGENUser1@ap6023fems.us.oracle.com
Summary
In this example, we created a simple web service that returned a list of users and their email addresses. We used a SQL statement to return the data and we renamed the fields to match the vendor’s requirements. We also showed how to test the service using HTTP and curl. We also showed how to get metadata back from the service to help with debugging. We also showed how to get the service to return XML and CSV.
This is a production-ready web service that was created in under 5 minutes. (Not counting the security setup.)
3 - Which SWS Method Should I Use?
SWS ships with two PeopleSoft service operations and one important sub-choice inside the config-based service. This page is a visual, one-page answer to “which one do I use?” — pick the path at the bottom of the flowchart, then follow the link to the detail page for that path.
Most admins will land on CHG_SWS (config-based) with PsoftQL syntax — that is the 95% answer. The diagram below confirms when to reach for the other two options instead.
Decision Flowchart
flowchart TD
start([Need to expose PeopleSoft data via REST]) --> q1{Is the caller a highly<br/>trusted internal<br/>integration platform?<br/><br/>e.g. MuleSoft,<br/>Snaplogic, Boomi}
q1 -->|Yes, and they can craft PsoftQL themselves| psoftqlws[CHG_SWS_PSOFTQL<br/><br/>client sends PsoftQL<br/>in the POST body<br/><br/>advanced · high-trust only]:::advanced
q1 -->|No — third-party,<br/>standard REST client,<br/>or locked-down use case| config[CHG_SWS<br/><br/>admin-configured GET service<br/>the 95% path]:::standard
config --> q2{What syntax inside<br/>the config?}
q2 -->|Need CSV output, or<br/>SQL-function data translation,<br/>or flat rowset data| sql[SQL statement]:::sql
q2 -->|Need nested parent/child data,<br/>pagination, auto EFFDT /<br/>EFF_STATUS / EFFSEQ,<br/>or all fields auto-exported| psoftql[PsoftQL statement<br/><br/>the default inside most configs]:::psoftql
classDef advanced fill:#fde2e2,stroke:#c0392b,stroke-width:2px,color:#222
classDef standard fill:#dff0d8,stroke:#3c763d,stroke-width:2px,color:#222
classDef sql fill:#e7f3fb,stroke:#289dd0,stroke-width:2px,color:#222
classDef psoftql fill:#d9f3f3,stroke:#5ac5c5,stroke-width:2px,color:#222Path 1 — CHG_SWS_PSOFTQL (Advanced)
This is the advanced service. The client POSTs a PsoftQL request body directly to PeopleSoft, and SWS returns structured JSON or XML that mirrors the PeopleSoft record layout. It is powerful — the caller can request any whitelisted table at will — but that power lives with the client, not with your admin configuration.
Only use CHG_SWS_PSOFTQL when the caller is a highly trusted internal integration platform such as MuleSoft, Snaplogic, or Boomi, and your team is comfortable that the caller can craft PsoftQL correctly. It is also useful while prototyping new SWS configurations. See Service Operation CHG_SWS_PSOFTQL for request/response details and the security model.
Path 2 — CHG_SWS (Config-Based GET)
This is the default path and what 95% of your web services will use. A PeopleSoft power-user configures the URL path, parameters, security grid, and the statement that runs — the client just calls a normal REST GET. All the PeopleSoft knowledge lives in the configuration row, not on the client.
Use CHG_SWS any time the caller is a third party, a standard REST client, or any integration where you want the admin (not the client) to define what data is exposed and how. See the SWS Configuration page for the full configuration walkthrough.
Sub-Decision — SQL or PsoftQL Inside the Config?
Inside a CHG_SWS configuration you choose one syntax type. Here is the short version of the trade-off:
Choose SQL when you need:
- CSV output (PsoftQL does not produce CSV)
- Data translation via SQL functions, joins across records, or aliases
- Flat, row-shaped results rather than nested parent/child trees
- Full hand-control over the
WHEREclause, joins, and effective-date logic
Choose PsoftQL when you want:
- Nested parent/child data (one person, many phones, many addresses) in a single response
- Pagination out of the box
- Automatic EFFDT, EFF_STATUS, and EFFSEQ handling — no SQL required
- All record fields auto-exported without hard-coding the select list
For the full, authoritative feature comparison (JSON/XML/CSV support, pagination, effective-date handling, etc.) see the Syntax Types table in the SWS Configuration page.
At a Glance
- Default choice:
CHG_SWSconfig-based service with PsoftQL syntax. - Reach for SQL inside a config when you need CSV output or SQL-side data translation.
- Reach for
CHG_SWS_PSOFTQLonly when the caller is a highly trusted internal iPaaS platform that can craft PsoftQL itself.
4 - What is HTTP and REST
HTTP Quick Start
This is a quick and succinct background on HTTP and REST concepts. We provide this here to give readers who are new to the Web Service concept a short introduction to HTTP syntax and REST concepts, as this documentation assumes that you have a basic understanding of the terminology and concept. If you want to understand HTTP, see the recommended tools section for some recommendations.
In the world of web development, the Hypertext Transfer Protocol (HTTP) serves as the foundation for communication between web browsers and servers. HTTP enables the exchange of information, such as web pages, images, and data. In this article, we will explore the basic concepts of HTTP, including requests, responses, and the syntax used to send and receive information between clients and servers.
HTTP Requests
When you type a website URL into your web browser’s address bar and hit enter, your browser sends an HTTP request to the server hosting that website. HTTP requests are made up of several components:
Request Method: The request method specifies the type of action the client wants to perform on the server. The two most common methods are:
- GET: This method is used to retrieve data from the server. It is typically used when you visit a website or fetch information.
- POST: This method is used to send data to the server. It is commonly used when you submit a form or upload a file.
URL/URI: The Uniform Resource Locator (URL) or Uniform Resource Identifier (URI) identifies the specific resource the client wants to access. It typically includes the domain name and the path to the resource on the server.
Headers: Headers contain additional information about the request, such as the type of content being sent, accepted content types, authentication credentials, and more. Headers provide crucial context to the server and allow the client and server to understand each other’s capabilities and requirements.
Parameters: Parameters are additional pieces of data that can be included with an HTTP request. They provide specific instructions to the server or help filter and narrow down the requested data. Parameters are often used in GET requests as query parameters, allowing the client to pass data in the URL.
HTTP Responses
When the server receives an HTTP request, it processes the request and sends back an HTTP response. An HTTP response consists of the following components:
Status Code: The status code indicates the outcome of the server’s attempt to fulfill the request. Some common status codes include:
- 200 OK: The request was successful, and the server is returning the requested data.
- 404 Not Found: The requested resource could not be found on the server.
- 500 Internal Server Error: An unexpected error occurred on the server.
Headers: Similar to request headers, response headers provide additional information about the response, such as the content type, cache-control directives, cookies, and more.
Response Body: The response body contains the actual data or content requested by the client. For example, if the client requested a web page, the response body would contain the HTML content of that page.
Syntax and Examples
HTTP requests and responses follow a specific syntax. Here are examples of GET and POST requests:
- GET Request:
GET /api/products?id=123 HTTP/1.1
Host: api.example.com
Accept: application/json
In the above example, the client is making a GET request to the server’s /api/products endpoint, passing the id parameter with a value of 123. The request also includes the Host header, specifying the server’s domain, and the Accept header, indicating that the client prefers a response in JSON format.
- POST Request:
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
In this example, the client is making a POST request to the server’s `/api
Understanding REST APIs and Parameter Passing with HTTP
Within the realm of HTTP, a powerful architectural style called REST (Representational State Transfer) has emerged as a standard for designing web APIs. SWS uses REST concepts to provide GET web services. Let’s quickly introduce a few concepts.
What is REST?
REST is an architectural style that provides a set of guidelines for designing networked applications. It emphasizes simplicity, scalability, and interoperability between systems. RESTful APIs (Application Programming Interfaces) enable different software applications to communicate with each other by leveraging the existing HTTP protocol.
In a RESTful architecture, resources (such as data or services) are identified by unique URLs called URIs (Uniform Resource Identifiers). These resources can be accessed and manipulated using standard HTTP methods like GET, POST, PUT, DELETE, etc. By following the principles of REST, developers can create APIs that are easy to understand, consume, and extend.
Understanding Parameters
In the context of REST APIs, parameters play a crucial role in specifying additional information for requests and responses. They allow clients (the applications making the requests) and servers (the applications serving the requests) to exchange data and perform specific actions.
Parameters can be classified into two main types: query parameters and path parameters.
- Query Parameters
Query parameters are used to filter, sort, or paginate data. They are appended to the end of a URL after a question mark ? and separated by ampersands &. For example:
GET https://api.example.com/products?category=electronics&sort=price&limit=10
In the above example, the query parameters are category=electronics, sort=price, and limit=10. These parameters provide additional instructions to the server, such as retrieving only electronic products, sorting them by price, and limiting the response to 10 items.
- Path Parameters
Path parameters are used to identify a specific resource within a URL path. They are denoted by a placeholder surrounded by curly braces ‘{}’. For example:
GET https://api.example.com/products/{id}
In the above example, the {id} placeholder represents a path parameter that would be replaced with an actual value when making a request. For instance, to retrieve the details of a product with an ID of 123, the URL would be:
GET https://api.example.com/products/123
Path parameters are useful when you want to interact with a specific resource or perform operations on it, such as updating or deleting it.
Conclusion
REST APIs have become the de facto standard for building web services due to their simplicity, scalability, and compatibility with the HTTP protocol. Understanding how parameters are passed using HTTP is essential for effectively working with RESTful APIs. By utilizing query parameters and path parameters, clients can provide additional instructions to the server and interact with specific resources. This empowers developers to build flexible and powerful applications that can seamlessly communicate with other services over the web.
5 - Recommended Tools
When working with SWS to configure new web services you will want some simple tools on your machine that you can quickly test new services. Having your own local tools will speed up your development and troubleshooting time significantly.
The tools we recommend to use are:
- Visual Studio Code - The only text editor you should be using!
- A great text editor with a huge list of plugins for editing and working with XML, JSON, encodings, etc.
- I really like the HTTPYac extension. It can replace Postman in many situations. It has some pretty good documentation.
- The key benefit here is that your HTTP request syntax is in local text files and you can easily check them into Git or do other types of backups.
- Chris uses this combination of tools to do 98% of development, troubleshooting and testing and is likely all you need.
- Use Hurl.dev for Automated API testing.
- You need to understand HTTP to use this tool and the learning curve can be steep. However, if you want to set up a simple automated HTTP test, I highly recommend learning it.
- Hurl is used in the development of SWS!
- Postman
- This is the default choice for most people. However, I have found that it has gotten too bloated with features for what I use it for. However, it is a great product!
- hoppscotch.io is a good alternative to Postman.
curlis also a tried and true tool for the techies.
Understanding HTTP Syntax
If you don’t have a firm understanding of HTTP concepts, I highly recommend that you read this concise book.
We will be documenting most HTTP calls in HTTP syntax in this documentation so you must have a general understanding of HTTP. If you prefer a more visual instruction I suggest you Search YouTube for HTTP introductions
6 - SWS Alternatives
You might be reading this page because you are trying to decide if SWS is right for your organization. Let’s look at what you would do if you did not have SWS. There are a few alternatives to our SWS solution. Let’s see how they compare.
Bespoke Web Services
The main alternative to SWS is to create a bespoke web service for each client or vendor and each piece of data. This is the traditional way of doing things. It is expensive and time-consuming. It is also very inflexible.
If we take the PeopleSoft Campus module as an example, a software vendor may need to integrate with Student Enrollment, Configuration data like Terms and other Academic Setup data, Student Bio data, Student Grades, and Invoices. This is a very common integration pattern.
With each new vendor, a custom bespoke web service may need to be created. You often may have very similar web services returning mostly the same data but with some slight variations.
SWS can run in any PeopleSoft database, but our example here is focused on Campus Solutions.
left to right direction
skinparam sequenceArrowThickness 3
Title: The SWS Alternative! Web Service Sprawl!
Package "PeopleSoft" {
rectangle "Terms" as rec.terms #FFD3B0
rectangle "Student Bio data" as rec.students #FFD3B0
rectangle "Student Grades" as rec.grades #FFD3B0
rectangle "Student Enrollment" as rec.se #FFD3B0
rectangle "Invoices" as rec.invoices #FFD3B0
' package "Bespoke Web Services" {
rectangle "Terms\nWeb Service" as ib.rec.terms #FF6969
rectangle "Student Bio data\nWeb Service" as ib.rec.students #FF6969
rectangle "Student Bio data\nWeb Service\nVersion 2" as ib.rec.students2 #FF6969
rectangle "Student Grades\nWeb Service" as ib.rec.grades #FF6969
rectangle "Student Enrollment\nWeb Service" as ib.rec.se #FF6969
rectangle "Student Enrollment\nWeb Service \nVersion 2" as ib.rec.se2 #FF6965
rectangle "Invoices\nWeb Service" as ib.rec.invoices #FF6969
' }
ib.rec.terms <-- rec.terms
ib.rec.students <-- rec.students
ib.rec.students2 <-- rec.students
ib.rec.grades <-- rec.grades
ib.rec.se <-- rec.se
ib.rec.se2 <-- rec.se
ib.rec.invoices <-- rec.invoices
' rectangle "SWS - Web Service\n\n(Single Web Service)\nReplaces all " as ib.sws #limeGreen
' ib.sws -[#limeGreen,thickness=3,dashed]-> rec.terms
' ib.sws -[#limeGreen,thickness=3,dashed]-> rec.students
' ib.sws -[#limeGreen,thickness=3,dashed]-> rec.grades
' ib.sws -[#limeGreen,thickness=3,dashed]-> rec.se
' ib.sws -[#limeGreen,thickness=3,dashed]-> rec.invoices
}
rectangle "LMS Integration Partner" as client #A6D0DD
rectangle "Student Success\nIntegration Partner" as client2 #A6D0DD
rectangle "Payment\nIntegration Partner" as client3 #A6D0DD
client <-- ib.rec.terms: GET
client <-- ib.rec.students: GET
client <-- ib.rec.grades: GET
client <-- ib.rec.se: GET
client2 <-- ib.rec.students2: GET
client2 <-- ib.rec.grades: GET
client2 <-- ib.rec.se2: GET
client3 <-- ib.rec.invoices: GET
' client -[#limeGreen,thickness=3,dashed]-> ib.sws
' client2 -[#limeGreen,thickness=3,dashed]-> ib.sws
' client3 -[#limeGreen,thickness=3,dashed]-> ib.sws
If you are a Software vendor trying to integrate with a PeopleSoft customer then you might develop 5 unique web services for the five unique areas you are trying to integrate with if you are NOT using SWS.
- You have a PeopleSoft application with 5 different web services.
- Each web service is designed for a specific vendor or client.
- Each client may have customizations that are hard to support in the traditional approach without access to the client’s PeopleSoft development instances or support from the client’s PeopleSoft development team.
- Each client may have different data filtering requirements.
- Code patches can take months to deploy to all clients and some clients may not be able to take the patch at all or they don’t have the resources to deploy the patch.
We have developed vendor solutions similarly and this is the reason we developed SWS. We wanted to make it easier for vendors to integrate with PeopleSoft, and we wanted to make it easier for PeopleSoft customers to integrate with third-party vendors. You can read more in the SWS origin story
What is the cost of this approach?
You can ask a developer to create a new web service for each user integration requirement. If a vendor commissioned the PeopleSoft application team to develop a new web service, the following process would likely be followed. This assumes you are a medium to large organization with a formal development process.
After years of developing web services for PeopleSoft customers, we have a good idea of the cost of developing a new web service and even wrote a book about the topic.
| Task | Minimum Estimated Person Hours | Maximum Estimated Person Hours |
|---|---|---|
| Gather Requirements | 5 | 10 |
| Write a technical specification | 5 | 10 |
| Technical Design Review | 2 | 10 |
| Create and unit test code | 8 | 40 |
| Functional Testing | 8 | 40 |
| Code Review | 2 | 10 |
| Code Migration | 2 | 4 |
| Bug Fixes | 4 | 10 |
| Totals | 36 Hours - $3,600 @ $100/Hour | 130 Hours - $13,000 @ $100/Hour |
- If you value your developer’s time at roughly $100 an hour. Then the cost to develop a single new web service is somewhere between $3,600 and $13,000.
- With SWS, that amount can be drastically reduced. In some cases, it can take just a few minutes to create a new web service and have it deployed in production.
Query Access Web Services
We have a KB article called Reporting Web Services: Using the REST Web Services to run a Query which demonstrates how you can make a “web service” out of a PeopleSoft query manager query. This can be an effective tool to generate web services.
However, the SWS offers many advantages over this delivered functionality.
- You have better control over the field names in the output.
- SWS offers more output encoding types
- The PeopleSoft query tool imposes unneeded complexity with data security and query tree security that often just gets in the way.
- SWS supports more advanced SQL and you are not forced into the SQL generated by query manager.
How does SWS Make it better?
- SWS is a single web service that can be used for most integrations.
- SWS is a single web service that can be used for all clients.
- SWS is a single web service that can be used for all vendors.
- SWS is a single web service that can be used for all data.
- SWS provides a consistent configuration framework for all clients and vendors.
left to right direction
skinparam sequenceArrowThickness 3
Title: The SWS Alternative! Web Service Sprawl!
Package "PeopleSoft" {
rectangle "Terms" as rec.terms #FFD3B0
rectangle "Student Bio data" as rec.students #FFD3B0
rectangle "Student Grades" as rec.grades #FFD3B0
rectangle "Student Enrollment" as rec.se #FFD3B0
rectangle "Invoices" as rec.invoices #FFD3B0
' package "Bespoke Web Services" {
' rectangle "Terms\nWeb Service" as ib.rec.terms #FF6969
' rectangle "Student Bio data\nWeb Service" as ib.rec.students #FF6969
' rectangle "Student Bio data\nWeb Service\nVersion 2" as ib.rec.students2 #FF6969
' rectangle "Student Grades\nWeb Service" as ib.rec.grades #FF6969
' rectangle "Student Enrollment\nWeb Service" as ib.rec.se #FF6969
' rectangle "Student Enrollment\nWeb Service \nVersion 2" as ib.rec.se2 #FF6965
' rectangle "Invoices\nWeb Service" as ib.rec.invoices #FF6969
' }
' ib.rec.terms <-- rec.terms
' ib.rec.students <-- rec.students
' ib.rec.students2 <-- rec.students
' ib.rec.grades <-- rec.grades
' ib.rec.se <-- rec.se
' ib.rec.se2 <-- rec.se
' ib.rec.invoices <-- rec.invoices
rectangle "SWS - Web Service\n\n*Single Web Service\n*Configuration Based\n* No Hard Coding" as ib.sws #limeGreen
ib.sws <-[#limeGreen,thickness=3,dashed]- rec.terms
ib.sws <-[#limeGreen,thickness=3,dashed]- rec.students
ib.sws <-[#limeGreen,thickness=3,dashed]- rec.grades
ib.sws <-[#limeGreen,thickness=3,dashed]- rec.se
ib.sws <-[#limeGreen,thickness=3,dashed]- rec.invoices
}
rectangle "LMS Integration Partner" as client #A6D0DD
rectangle "Student Success\nIntegration Partner" as client2 #A6D0DD
rectangle "Payment\nIntegration Partner" as client3 #A6D0DD
' client <-- ib.rec.terms
' client <-- ib.rec.students
' client <-- ib.rec.grades
' client <-- ib.rec.se
' client2 <-- ib.rec.students2
' client2 <-- ib.rec.grades
' client2 <-- ib.rec.se2
' client3 <-- ib.rec.invoices
client <-[#limeGreen,thickness=3,dashed]- ib.sws: GET
client2 <-[#limeGreen,thickness=3,dashed]- ib.sws: GET
client3 <-[#limeGreen,thickness=3,dashed]- ib.sws: GET