simplecomplex / http
High-level HTTP client and (Slim) service utility. Client provides response validation and mocking; service provides standardized and predictable responses.
Installs: 168
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/simplecomplex/http
Requires
- php: >=7.0
- ext-ctype: *
- psr/log: ^1.0
- simplecomplex/cache: ^1.3 || dev-develop
- simplecomplex/config: ^2.1 || dev-develop
- simplecomplex/inspect: ^3 || ^2.2.5 || dev-develop
- simplecomplex/locale: ^2.1 || dev-develop
- simplecomplex/restmini: ^1.1.2 || dev-develop
- simplecomplex/utils: ^1.9 || ^2.0 || dev-develop
- simplecomplex/validate: ^2.1 || ^1.0 || dev-develop
Suggests
- slim/slim: ^3.8.1
README
High-level HTTP client and (Slim) service utility.
Client provides response validation and mocking.
Service provides standardized and predictable responses.
▹ Client
Request options
The HttpClient->request() method accepts it's own options
as well as options for the underlying RestMini Client.
Own options
- (bool) debug_dump: log request and response
- (bool|arr) cacheable: cache response/load response from cache
- (bool|arr) validate_response: validate the response body against a validation rule set
- (bool|arr) mock_response: don't send the request, return predefined mock response
- (int) retry_on_unavailable: millisecs; try again later upon
503 Service Unavailable|host not found|connection failed - (arr) require_response_headers: list of response header keys required
- (bool) err_on_endpoint_not_found: err on 404 + HTML response
- (bool) err_on_resource_not_found: err on 204 or 404 + JSON response
- (arr) log_warning_on_status: key is status code, value is true
Options processing
Apart from options passed directly to HttpClient->request()
there may also exist settings (see Config) for the:
- provider: the service host
- service: a group of endpoints
- endpoint: the actual endpoint
- method: literal HTTP method or an alias (like GET aliases index and retrieve)
During request preparations settings and options get merged, so that
– options override method settings, which override endpoint settings, which override... (you get it).
Sounds like a lot of work, but it isn't really.
▹▹ Client CLI commands
(remote) Service configuration
# Show provider settings. php cli.php config-get -a global http-provider.prvdr # Show service settings. php cli.php config-get -a global http-service.prvdr.example-service # Show endpoint settings. php cli.php config-get -a global http-endpoint.prvdr.example-service.ndpnt # Show method settings. php cli.php config-get -a global http-method.prvdr.example-service.ndpnt.GET
Validation rule sets
# Show cached validation rule set. php cli.php cache-get http-response_validation-rule-set prvdr.example-service.ndpnt.GET # Delete cached validation rule set. php cli.php cache-delete http-response_validation-rule-set prvdr.example-service.ndpnt.GET
Mock responses
# Show cached mock response. php cli.php cache-get http-response_mock prvdr.example-service.ndpnt.GET # Delete cached mock response. php cli.php cache-delete http-response_mock prvdr.example-service.ndpnt.GET
▹▹ Client error codes
For every error code there's an equivalent prefab safe and user-friendly (localizable) error message.
unknown: overall error fallbacklocal-unknown: local error fallbacklocal-algo: in-package logical errorlocal-use: invalid argument et al.local-configuration: bad config varlocal-option: bad option varlocal-init: RestMini Client or cURL cannot requesthost-unavailable: DNS or actually no such hostservice-unavailable: status 503 Service Unavailabletoo-many-redirects: too many redirectstimeout: cURL 504timeout-propagated: status 504 Gateway Timeoutresponse-none: cURL 500 (RestMini Client 'response-false')remote: status 500 Internal Server Errorremote-propagated: remote says 502 Bad Gatewaymalign-status-unexpected: unsupported 5xx statusendpoint-not-found: status 404 + Content-Type not JSON (probably HTML); no such endpointresource-not-found: status 204, status 404 + Content-Type JSON; no such resource (object)remote-validation-bad: 400 Bad Requestremote-validation-failed: 412 Precondition Failed, 422 Unprocessable Entityresponse-type: content type mismatchresponse-format: parse errorbenign-status-unexpected: unsupported non-5xx statusheader-missing: setting/option require_response_headersresponse-validation: response body validation failure; service will send X-Http-Response-Invalid header
▹ Service
Producing a service response is not as hard as requesting a remote service,
so the service part of Http is not as rich as the client part.
It is assumed that one will simply echo something and send some headers
– or use a service framework like Slim.
The HttpServiceSlim class suggest means of interacting with Slim, and Http includes a simple example.
@todo
And Http also provides a few other service utilities.
Allowing Cross Origin requests
Preferably only at development site. Necessary when developing Angular-based frontend.
Place a .cross_origin_allow_sites text file in document root, containing list allowed sites, like:
http://localhost:4200,http://my-project.build.local.host:80
▹▹ Service error codes
For every error code there's an equivalent prefab safe and user-friendly (localizable) error message.
unknown: overall fallbackrequest-unacceptable: (some kind of) bad request;HttpResponseRequestUnacceptableunauthenticated: authentication (login) failure;HttpResponseRequestUnauthenticatedunauthorized: authorization (permission) failure;HttpResponseRequestUnauthorizedrequest-validation: request header/argument validation failure;HttpResponseRequestInvalidfrontend-response-format: frontend only; parse errorfrontend-response-validation: frontend only; response validation failure
Service and client combined
Standardized wrapped response body
A service requestor should never be in doubt whether a request to your service went alltogether well.
HttpClient->request() returns HttpResponse object:
- status
int: suggested status to send to requestor - headers
array: suggested headers to send - body
HttpResponseBody- success
bool - status
int: status received from remote service - data
mixed|null: that actual data (on success) - message
string|null: safe and user-friendly message (on failure) - code
int: error code (on failure), or optionally some other flag (on success)
- success
- originalHeaders
array: headers received – not to be sent to requestor - validated
bool|null: whether the response was validated, and then the outcome
The general idea is to always send a response body containing metadata about the procedings – success, status, code.
And – on failure – a prefab safe and user-friendly message, which the client can use to inform the visitor
(instead of just failing silently/ungracefully).
When exposing a service that does a remote request, the service should however have access to more detailed info
about the remote request/response
– therefore the further wrapping in an object that suggests status and headers (et al.).
▹ Service response headers
Http uses a number of custom response headers, to flag stuff to the client.
Some are issued by HttpClient upon every remote request (the original/final statuses).
Others are only issued if a service uses/sends one of the prefab HttpResponse extensions.
- (int)
X-Http-Original-Status: status received from remote service (or interpretated ditto) - (int)
X-Http-Final-Status: final status to be sent to client X-Http-Response-Invalid: response validation failure;HttpResponseResponseInvalidX-Http-Mock-Response:HttpClientnever called remote service; used prefab mock responseX-Http-Request-Invalid: request header/argument validation failure;HttpResponseRequestInvalidX-Http-Request-Unacceptable: (some kind of) bad request;HttpResponseRequestUnacceptableX-Http-Request-Unauthenticated: authentication (login) failure;HttpResponseRequestUnauthenticatedX-Http-Request-Unathorized: authorization (permission) failure;HttpResponseRequestUnauthorized
Requirements
- PHP >=7.0
- PSR-3 Log
- SimpleComplex Utils
- SimpleComplex Cache
- SimpleComplex Config
- SimpleComplex Locale
- SimpleComplex Validate
- SimpleComplex RestMini
- SimpleComplex Inspect