-
-
Save heisian/fdd5b42e35e98c906488eca0193f21c9 to your computer and use it in GitHub Desktop.
import Xhr from 'Xhr' | |
const xhr = new Xhr() | |
// Or alternatively, xhr is just functional: | |
// import xhr from 'xhr' | |
// Assume xhr instance (or functional equivalent) is being passed in | |
;(async (xhr) => { | |
// Current API | |
let response = await xhr('patch') | |
.user(2) | |
.identity(2) | |
.data({ | |
email: '[email protected]', | |
password: 'somethignReally.Good!', | |
nameFirst: 'Timothy', | |
nameLast: 'Huang', | |
birthDate: '1985-10-21', | |
gender: 'Male', | |
}) | |
.fetch() | |
// Hypothetical API, closure/DI-style | |
response = await xhr.patch((request) => { | |
request.path.user(2).identity(2) | |
request.headers({ 'Content-Type': 'application/json' }) | |
request.data({ | |
email: '[email protected]', | |
password: 'somethignReally.Good!', | |
nameFirst: 'Timothy', | |
nameLast: 'Huang', | |
birthDate: '1985-10-21', | |
gender: 'Male', | |
}) | |
}) | |
// Hypothetical again, using destructuring | |
response = await xhr.patch(({ path, headers, data }) => { | |
path.user(2).identity(2) | |
headers({ 'Content-Type': 'application/json' }) | |
data({ | |
email: '[email protected]', | |
password: 'somethignReally.Good!', | |
nameFirst: 'Timothy', | |
nameLast: 'Huang', | |
birthDate: '1985-10-21', | |
gender: 'Male', | |
}) | |
}) | |
// Hypothetical again, with custom path and query params | |
response = await xhr.get(({ path, params, headers, data }) => { | |
path('/some/custom/path') | |
params({ | |
some: 'data', | |
will: 'getQueryStringified', | |
}) | |
}) | |
}) |
Calling patch feels off xhr.patch
as patch usually means some sort of update to an existing thing in my experience.
response = await xhr.patch((request) => {}
implies to me that the internals is going to call this back with a request
param that is used by consumer to set these properties, and then Xhr
will use that to set things up internally and then execute the fetch
; but why not then just have these passed in directly by client and do the same?
For the last custom path and query params
one, I first read the { path, params, headers, data }
inputs as properties, but they're actually methods the consumer uses to inject the values back to Xhr
. Again, I think just letting the consumer do it and pass in is more straight forward.
I do like the idea of having convenience methods based on HTTP verb. It's familiar based on old jQuery days, and I think we could share same GET vs. POST interface as setting up xhr
directly.
Here's my take on going all in on DI:
/*
interface XhrConfig {
baseUrl?: string, /* internall will have a sensible default */
httpMethod: HttpMethodType,
requestOptions: XhrOptions = {}
pathBuilder: PathBuilder,
requestBody?: string, /* only for POST/PUT etc. */
}
*/
function Xhr({ baseUrl, method, path, requestBody }: XhrConfig) {...}
export Xhr
import Xhr from 'Xhr'
import pathBuilder from 'PathBuilder'
const xhr = new Xhr()
// GET
function termPolicyXhr(userId, identityId, termPolicyId) {
return (method): Promise<XhrResponse> {
// You still have the nice chaining for PathBuilder
const path = new pathBuilder()
.user(userId)
.identity(identityId)
.termPolicy(termPolicyId)
// Xhr calls fetch internally
return xhr(/* baseUrl--optional, maybe has a default */, method, path, /* requestBody not meaningful here */)
}
}
// POST
function termPolicyCreateXhr(userId, identityId, termPolicyId, requestBody) {
return (method): Promise<XhrResponse> {
// You still have the nice chaining for PathBuilder
const path = new pathBuilder()
.user(userId)
.identity(identityId)
.termPolicy(termPolicyId)
// Xhr calls fetch internally
return xhr(myBaseUrlOverride, method, path, requestBody)
}
}
how would I invoke termPolicyCreateXhr
in this example?
perhaps,
import Xhr from 'xhr'
import termPolicyCreateXhr from 'termPolicyCreateXhr'
const xhrInstance = new Xhr()
;(async() => {
const response = await termPolicyCreateXhr(1, 2, 3, {
some: 'data',
})
})()
simplified, after speaking IRL w/ @roblevintennis:
import xhr from 'xhr'
;(async() => {
const path = new xhr.path
.user(userId)
.identity(identityId)
.termPolicy(termPolicyId)
// Xhr calls fetch internally
const { err, response } = await xhr({
baseURL: 'somethingelse.com',
method: xhr.POST,
path,
{ some: 'data' },
})
if (err) {
// handle it
}
})()
@zach-ethos @roblevintennis what do ya'll think about the "Hypothetical" API vs. what
Xhr
currently has?