Skip to content

Commit cefda99

Browse files
committed
Port HTTP transport from ponylang/http to ponylang/courier
Replace the HTTP handler factory pattern (25 types: 8 requesters + 8 handler factories + 8 handlers + RequestFactory) with courier's actor-based connection model (6 types: 4 request actors + 1 SSL factory + 1 shared interface). Each API call creates a short-lived actor owning an HTTPClientConnection. Consolidation by response pattern: POST+PATCH share JsonRequester (differ by method/expected status), DELETE+PUT share NoContentRequester, paginated+search share LinkedJsonRequester via a LinkedResultReceiver interface. Breaking change: Credentials.auth changes from net.TCPConnectAuth to lori.TCPConnectAuth. Authorization header moves from legacy "token" format to "Bearer" format (GitHub accepts both). Public API is otherwise preserved — all operation primitives, model classes, OO convenience methods, and pagination work the same way.
1 parent e18bea0 commit cefda99

65 files changed

Lines changed: 716 additions & 1214 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.release-notes/next-release.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ end
3333
gist.update_gist(updates)
3434
```
3535

36-
This also adds three new HTTP infrastructure classes: `HTTPPatch` (PATCH with JSON response), `HTTPPut` (PUT expecting 204), and `HTTPCheck` (GET returning Bool based on status code 204/404).
3736

3837
## Add query parameters to GetRepositoryIssues
3938

.release-notes/port-to-courier.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Port HTTP transport from ponylang/http to ponylang/courier
2+
3+
The HTTP transport layer has been replaced with ponylang/courier, which uses an actor-based connection model instead of the handler factory pattern. All public API operations work the same way, but `Credentials.auth` has changed type.
4+
5+
Before:
6+
```pony
7+
use "net"
8+
9+
let auth = TCPConnectAuth(env.root)
10+
let creds = Credentials(auth, token)
11+
```
12+
13+
After:
14+
```pony
15+
use lori = "lori"
16+
17+
let auth = lori.TCPConnectAuth(env.root)
18+
let creds = Credentials(auth, token)
19+
```
20+
21+
Authorization headers now use `Bearer` format (`Authorization: Bearer <token>`) instead of the legacy `token` format. GitHub accepts both.

CLAUDE.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ Uses `corral` for dependency management. `make` automatically runs `corral fetch
1818

1919
## Dependencies
2020

21-
- `github.com/ponylang/http.git` -- HTTP client
22-
- `github.com/ponylang/net_ssl.git` (via http) -- SSL/TLS
21+
- `github.com/ponylang/courier.git` -- HTTP client (actor-based)
22+
- `github.com/ponylang/lori.git` (via courier) -- TCP connections
23+
- `github.com/ponylang/ssl.git` (via courier) -- SSL/TLS
2324
- `github.com/ponylang/web_link.git` -- RFC 8288 Link header parsing
2425
- `github.com/ponylang/json-ng.git` -- JSON parsing (immutable, persistent collections)
2526
- `github.com/ponylang/uri.git` -- RFC 6570 URI template expansion
@@ -52,16 +53,14 @@ github_rest_api/
5253
user.pony -- User model
5354
license.pony -- License model
5455
json_nav_util.pony -- JsonNavUtil (string_or_none for nullable JSON fields)
55-
paginated_list.pony -- PaginatedList[A] with prev/next page navigation
56+
paginated_list.pony -- PaginatedList[A] with prev/next page navigation, LinkedJsonRequester, LinkedResultReceiver
5657
_extract_pagination_links.pony -- Extracts prev/next URLs from Link headers (via web_link)
5758
request/ -- HTTP request infrastructure (temporary home, intended to be extracted to its own library)
58-
http.pony -- Credentials, ResultReceiver, RequestFactory
59-
http_get.pony -- JsonRequester (GET with JSON response)
60-
http_post.pony -- HTTPPost (POST with JSON response)
61-
http_patch.pony -- HTTPPatch (PATCH with JSON response, expects 200)
62-
http_delete.pony -- HTTPDelete (DELETE, expects 204)
63-
http_put.pony -- HTTPPut (PUT with no body, expects 204)
64-
http_check.pony -- HTTPCheck (GET returning Bool: 204=true, 404=false)
59+
credentials.pony -- Credentials (lori.TCPConnectAuth + token), ResultReceiver
60+
_ssl.pony -- SSLContextFactory (shared SSL context creation)
61+
json_requester.pony -- JsonRequester actor (GET/POST/PATCH with JSON response)
62+
no_content_requester.pony -- NoContentRequester actor (DELETE/PUT expecting 204)
63+
check_requester.pony -- CheckRequester actor (GET returning Bool: 204=true, 404=false)
6564
request_error.pony -- RequestError (status, response_body, message)
6665
json.pony -- JsonConverter interface, JsonTypeString utility
6766
query_params.pony -- QueryParams (URL query string builder with percent-encoding)
@@ -78,7 +77,7 @@ All API operations return `Promise[(T | RequestError)]`. The flow is:
7877
1. Operation primitive (e.g., `GetRepository`) creates a `Promise`
7978
2. Creates a `ResultReceiver[T]` actor with the promise and a `JsonConverter[T]`
8079
3. Builds URL using `ponylang/uri` RFC 6570 template expansion for path parameters
81-
4. Issues HTTP request via `JsonRequester` / `HTTPPost` / `HTTPPatch` / `HTTPDelete` / `HTTPPut` / `HTTPCheck`
80+
4. Creates a short-lived request actor (`JsonRequester` / `NoContentRequester` / `CheckRequester` / `LinkedJsonRequester`) that owns an `HTTPClientConnection` from `ponylang/courier`
8281
5. On success, JSON is parsed and converted to model via `JsonConverter`
8382
6. Promise is fulfilled with either the model or a `RequestError`
8483

@@ -102,7 +101,7 @@ Models have methods that chain to further API calls:
102101

103102
### Auth
104103

105-
`Credentials` holds a `TCPConnectAuth` and an optional token string. `RequestFactory` sets `User-Agent`, `Accept: application/vnd.github.v3+json`, and `Authorization: token <token>` headers.
104+
`Credentials` holds a `lori.TCPConnectAuth` and an optional token string. Each request actor sets `User-Agent`, `Accept: application/vnd.github.v3+json`, and `Authorization: Bearer <token>` headers.
106105

107106
## Conventions
108107

@@ -115,7 +114,7 @@ Models have methods that chain to further API calls:
115114

116115
## Known TODOs in Code
117116

118-
1. Potential HTTP GET duplication with paginated variant (paginated_list.pony)
117+
None currently tracked.
119118

120119
## GitHub REST API Coverage Comparison
121120

corral.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"version": "0.1.0"
1010
},
1111
{
12-
"locator": "github.com/ponylang/http.git",
13-
"version": "0.6.4"
12+
"locator": "github.com/ponylang/courier.git",
13+
"version": "0.1.0"
1414
},
1515
{
1616
"locator": "github.com/ponylang/json-ng.git",

examples/create-gist-oo/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55

66
actor Main
77
new create(env: Env) =>
@@ -42,7 +42,7 @@ actor Main
4242
let token = cmd.option("token").string()
4343

4444
// ----- Create gist
45-
let auth = TCPConnectAuth(env.root)
45+
let auth = lori.TCPConnectAuth(env.root)
4646
let creds = Credentials(auth, token)
4747

4848
let files = recover val

examples/create-gist/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55

66
actor Main
77
new create(env: Env) =>
@@ -42,7 +42,7 @@ actor Main
4242
let token = cmd.option("token").string()
4343

4444
// ----- Create gist
45-
let auth = TCPConnectAuth(env.root)
45+
let auth = lori.TCPConnectAuth(env.root)
4646
let creds = Credentials(auth, token)
4747

4848
let files = recover val

examples/create-issue-comment-oo/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55
use "promises"
66

77
actor Main
@@ -39,7 +39,7 @@ actor Main
3939
let token = cmd.option("token").string()
4040

4141
// ----- Create issue comment
42-
let auth = TCPConnectAuth(env.root)
42+
let auth = lori.TCPConnectAuth(env.root)
4343
let creds = Credentials(auth, token)
4444

4545
GitHub(creds).get_repo(owner, repo)

examples/create-issue-comment/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55

66
actor Main
77
new create(env: Env) =>
@@ -38,7 +38,7 @@ actor Main
3838
let token = cmd.option("token").string()
3939

4040
// ----- Create issue comment
41-
let auth = TCPConnectAuth(env.root)
41+
let auth = lori.TCPConnectAuth(env.root)
4242
let creds = Credentials(auth, token)
4343

4444
let p = CreateIssueComment(owner, repo, issue, comment, creds)

examples/create-label-oo/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55
use "promises"
66

77
actor Main
@@ -43,7 +43,7 @@ actor Main
4343
let token = cmd.option("token").string()
4444

4545
// ----- Create issue comment
46-
let auth = TCPConnectAuth(env.root)
46+
let auth = lori.TCPConnectAuth(env.root)
4747
let creds = Credentials(auth, token)
4848

4949
GitHub(creds).get_repo(owner, repo)

examples/create-label/main.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use "../../github_rest_api"
22
use "../../github_rest_api/request"
33
use "cli"
4-
use "net"
4+
use lori = "lori"
55

66
actor Main
77
new create(env: Env) =>
@@ -42,7 +42,7 @@ actor Main
4242
let token = cmd.option("token").string()
4343

4444
// ----- Create issue comment
45-
let auth = TCPConnectAuth(env.root)
45+
let auth = lori.TCPConnectAuth(env.root)
4646
let creds = Credentials(auth, token)
4747

4848
let p = CreateLabel(owner, repo, name, creds, color, description)

0 commit comments

Comments
 (0)