Documentation Index Fetch the complete documentation index at: https://docs.prism.byescaleira.com/llms.txt
Use this file to discover all available pages before exploring further.
Network Client
PrismNetwork provides a protocol-oriented HTTP client layer built on URLSession. Define type-safe requests, decode responses automatically, and swap implementations for testing.
Architecture
PrismNetworkClient Protocol defining request(on:with:) and redirect(from:). Program against this for testability.
PrismNetworkAdapter Actor-based URLSession implementation with caching, redirect capture, and status code validation.
PrismNetworkRequest Ties an endpoint to a response type. Default decoding via PrismEntity.
Basic Usage
1. Define an Endpoint
Endpoints describe a single API call — host, path, method, headers, and body:
import PrismNetwork
enum UserEndpoint : PrismNetworkEndpoint {
case list
case get ( id : String )
case create ( name : String , email : String )
var host: String { "api.example.com" }
var path: String {
switch self {
case . list : return "/v1/users"
case . get ( let id) : return "/v1/users/ \( id ) "
case . create : return "/v1/users"
}
}
var method: PrismNetworkMethod {
switch self {
case . list , . get : return . get
case . create : return . post
}
}
var headers: [ String : String ] {
[ "Content-Type" : PrismNetworkHeaderType. json . rawValue ]
}
var body: ( any Encodable) ? {
switch self {
case . create ( let name, let email) :
return [ "name" : name, "email" : email]
default :
return nil
}
}
}
2. Define a Request
A request ties an endpoint to a Decodable response type:
import PrismNetwork
struct User : PrismEntity , Sendable {
let id: String
let name: String
let email: String
}
struct ListUsersRequest : PrismNetworkRequest {
typealias Response = [User]
let endpoint: UserEndpoint = . list
}
struct GetUserRequest : PrismNetworkRequest {
typealias Response = User
let endpoint: UserEndpoint
init ( id : String ) {
self . endpoint = . get ( id : id)
}
}
3. Execute the Request
let client = PrismNetworkAdapter ()
// List all users
let users = try await client. request ( on : ListUsersRequest ())
// Get a single user
let user = try await client. request ( on : GetUserRequest ( id : "42" ))
print (user. name ) // "Alice"
Pass a DateFormatter when your API returns non-standard date formats:
let formatter = DateFormatter ()
formatter. dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let user = try await client. request (
on : GetUserRequest ( id : "42" ),
with : formatter
)
Redirect Handling
Capture redirect URLs without following them:
let redirectURL = try await client. redirect (
from : GetUserRequest ( id : "42" )
)
print (redirectURL) // https://api.example.com/v2/users/42
PrismNetworkAdapter Configuration
The adapter wraps URLSession and supports custom session configurations and caching:
let config = URLSessionConfiguration. default
config. timeoutIntervalForRequest = 30
let cache = URLCache (
memoryCapacity : 10 * 1024 * 1024 , // 10 MB
diskCapacity : 50 * 1024 * 1024 // 50 MB
)
let client = PrismNetworkAdapter (
configuration : config,
cache : cache
)
Error Handling
All errors are typed as PrismNetworkError:
do {
let user = try await client. request ( on : GetUserRequest ( id : "42" ))
} catch let error as PrismNetworkError {
switch error {
case . invalidURL : print ( "Bad URL" )
case . noConnectivity : print ( "No network" )
case . unauthorized : print ( "Auth required" )
case . forbidden : print ( "Access denied" )
case . badRequest : print ( "Invalid request" )
case . serverError : print ( "Server error" )
case . invalidResponse : print ( "Unexpected response" )
case . noCache : print ( "No cached data" )
}
}
PrismNetworkError automatically maps HTTP status codes: 400 → .badRequest, 401 → .unauthorized, 403 → .forbidden, 408/429/5xx → .serverError. It also maps URLError codes like .notConnectedToInternet to .noConnectivity.
Testing with Mock Clients
Because PrismNetworkClient is a protocol, you can create mock implementations:
actor MockNetworkClient : PrismNetworkClient {
var mockResponse: Any ?
func request < Request : PrismNetworkRequest >(
on request : Request,
with formatter : DateFormatter ?
) async throws -> Request.Response {
guard let response = mockResponse as? Request.Response else {
throw PrismNetworkError. invalidResponse
}
return response
}
func redirect < Request : PrismNetworkRequest >(
from request : Request
) async throws -> URL {
throw PrismNetworkError. invalidResponse
}
}
Next Steps
Type-Safe Endpoints Learn the full endpoint protocol and enum-based patterns.
Caching & Retry Add response caching and automatic retry policies.