Created
August 26, 2017 16:52
-
-
Save gilligan/dce2df5a4dbc168be21fe2fabbf7235c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
// So `declareService` receives a service declaration that provides some properties | |
// for creating a service including some functions for mapping service responses and | |
// query parameters. I thought it would be nice to parameterize `ServiceDeclaration` | |
// over the types of those mapping functions. | |
// | |
// Am I making sense? Does the *code* make any sense? If not how should I change it? | |
/* types.js -------------------------------------------------------- */ | |
interface ServiceDeclaration<Response, MappedResponse, QueryParams, MappedQueryParams> { | |
name: string, | |
servicePath: string, | |
transform(from: Response, to: MappedResponse): MappedResponse, | |
toQuery(from: QueryParams, to: MappedQueryParams): MappedQueryParams, | |
passThroughCacheHeaders: boolean, | |
serviceTimeout: number, | |
errorHandler: Function | |
} | |
/* declareService.js ---------------------------------------------- */ | |
const declareService = (decl: ServiceDeclaration<*, *, *, *>) => { | |
return { | |
createService(baseUrl) { | |
return { | |
name: decl.name, | |
read(req, res, params, config, callback) { | |
// fetch data using functions/props from decl | |
} | |
}; | |
} | |
}; | |
}; | |
/* fooService.js -------------------------------------------------- */ | |
type Response = {| bar: string |}; | |
type FooResponse = {| foo: string |}; | |
type FooParams = {| id: string |}; | |
type FooMappedParams = {| id: string, token: string |}; | |
const fooErrorHandler = (err) => { throw err }; | |
const fooTransform = (r: Response): FooResponse => { | |
return { | |
foo: r.bar | |
}; | |
}; | |
const fooQuery = (params: FooParams): FooMappedParams => { | |
return { | |
id: params.id, | |
token: 'token' | |
}; | |
}; | |
const fooDecl : ServiceDeclaration<Response, FooResponse, FooParams, FooMappedParams> = { | |
name: 'fooService', | |
servicePath: '/api/foo', | |
transform: fooTransform, | |
toQuery: fooQuery, | |
passThroughCacheHeaders: false, | |
serviceTimeout: 5000, | |
errorHandler: fooErrorHandler | |
}; | |
declareService(fooDecl); | |
/* barService.js -------------------------------------------------- */ | |
type _Response = {| bar: string |}; | |
type BarResponse = {| foo: string |}; | |
type BarParams = {| id: string |}; | |
type BarMappedParams = {| id: string, token: string |}; | |
const barErrorHandler = (err) => { throw err }; | |
const barTransform = (r: _Response): BarResponse => { | |
return { | |
foo: r.bar | |
}; | |
}; | |
const barQuery = (params: FooParams): BarMappedParams => { | |
return { | |
id: params.id, | |
token: 'token' | |
}; | |
}; | |
const barDecl : ServiceDeclaration<_Response, BarResponse, BarParams, BarMappedParams> = { | |
name: 'fooService', | |
servicePath: '/api/foo', | |
transform: barTransform, | |
toQuery: barQuery, | |
passThroughCacheHeaders: false, | |
serviceTimeout: 5000, | |
errorHandler: barErrorHandler | |
}; | |
declareService(barDecl); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Okay so let's try to make some sense of this. So we are talking about a React/Fluxible app which uses fetchr plugin for REST services. So somewhere in the code base we'll do something like ..
where
s
has to be something likeFor simple services we have
baseService.js
which exports adeclareService
function which takes an object "declaring" the service and returns aService
object as expected byfetchr
.So if you want to implement
someSimpleService.js
:which would then be used somewhere in the app setup code ...
ServiceDecl
type where functions are just typed asFunction
and be done with it. Having response types in there as parameters would definitely seem nice to me though.Not entirely sure why but nothing that I try with flow right now seems quite right. Did this explanation make it any less confusing? I hope so ;-)