On this page

Folder structure and routing

Each subfolder under endpoints/ corresponds to an endpoint type. The folder name within each type becomes the endpoint name in the API URL. Portway watches these folders and reloads configuration when files change.

In practice this means Portway derives your API routes from the endpoints/ folder hierarchy, so there is no route registration step at all. When you want different naming, the Namespace and DisplayName attributes let you override the derived route; that's an advanced setup covered further down.

Directory layout

txt
PortwayApi/
├── appsettings.json
├── web.config
├── *.db
├── log/
├── tokens/
├── environments/
│   ├── settings.json
│   ├── dev/
│   │   └── settings.json
│   ├── test/
│   │   └── settings.json
│   └── prod/
│       └── settings.json
└── endpoints/
    ├── SQL/
    │   └── Products/
    │       └── entity.json
    ├── Proxy/
    │   ├── Accounts/
    │   │   └── entity.json
    │   └── SalesOrder/
    │       └── entity.json
    ├── Webhooks/
    │   └── entity.json
    ├── Files/
    │   ├── CustomerData/
    │   │   └── entity.json
    │   └── Images/
    │       └── entity.json
    └── Static/
        └── Countries/
            └── entity.json

Route patterns

Endpoint type Folder path URL pattern
SQL endpoints/SQL/{Name}/entity.json /api/{env}/{Name}
Proxy endpoints/Proxy/{Name}/entity.json /api/{env}/{Name}
Composite endpoints/Proxy/{Name}/entity.json (Type: Composite) /api/{env}/composite/{Name}
Webhook endpoints/Webhooks/{Namespace}/{Name}/entity.json /api/{env}/{Namespace}/{Name}/{id}
File endpoints/Files/[{Namespace}/]{Name}/entity.json /api/{env}/files/[{Namespace}/]{Name}
Static endpoints/Static/{Name}/entity.json /api/{env}/{Name}

The endpoint name in the URL is case-sensitive and matches the folder name exactly.

The QUERY method

Sometimes a read needs more than a URL can comfortably carry. When your filters grow long, or you would simply rather not see query details sitting in access logs, the QUERY method (described in RFC 10008) offers a friendly alternative. It behaves much like a GET, except your criteria travel in the request body as JSON.

QUERY is a read, and only a read. It is safe and idempotent, so Portway routes it through the same code that serves GET (SQL selects, static content, and proxied reads) and never through anything that writes. Because it stays safe, the response is cacheable too, and Portway folds your request body into the cache key so that two different queries never share a cached answer.

You can opt an endpoint into QUERY by adding it to AllowedMethods:

json
{
  "DatabaseObjectName": "StockLevels",
  "AllowedMethods": ["QUERY"],
  "AllowedEnvironments": ["prod"]
}

A request then carries its criteria as JSON. Both the bare and $-prefixed OData field names are accepted, so you can reach for whichever feels natural:

http
QUERY /api/prod/Inventory/StockLevels
Content-Type: application/json
Authorization: Bearer <token>

{
  "select": "Sku,Warehouse,Quantity",
  "filter": "Quantity gt 0 and Warehouse eq 'AMS'",
  "orderby": "Quantity desc",
  "top": 50
}

The response mirrors the equivalent GET, including pagination headers and an optional Content-Location that points at the GET URL which would return the same results.

Note: QUERY expects a JSON body, so please remember to include Content-Type: application/json. A request without it is answered with 415 Unsupported Media Type, which is really just a gentle nudge rather than a hard failure.

SQL, Proxy, and Static endpoints all treat QUERY as a read. Composite and Webhook endpoints are about orchestration and writes, so they kindly decline QUERY with 405 Method Not Allowed.

Folder permissions

Grant the IIS Application Pool identity read/write access to the deployment directory:

powershell
# ApplicationPoolIdentity
icacls "C:\Apps\Portway" /grant "IIS AppPool\PortwayAppPool:(F)" /T /C

# Custom service account
icacls "C:\Apps\Portway" /grant "DOMAIN\SVC_PORTWAY:(F)" /T /C
Folder Minimum permission Reason
log/ Read/Write Log file creation and rotation
tokens/ Read/Write Token file management
environments/ Read Configuration reads
endpoints/ Read Configuration reads
Root Read/Write auth.db and temporary files

WARNING

Do not expose the deployment directory via web browsing. Verify that web.config disables directory listing.

Next steps

Last updated: 2026-07-23