ttt-rest-service
JS Library which gives functionallity to create services for client-server communication with REST style
Library provides:
- default Service
- Composite classes:
- Fetcher
- ResponseProcessor
- MimeParser
- Factories:
- FetcherFactory
- ServiceFactory
Use composite classes to create your own service if default Service does not fulfill the needs
Installation
npm i --save ttt-rest-service
Getting Started
import {
Fetcher,
MimeParser,
ResponseProcessor,
Service,
FetcherFactory,
ServiceFactory
} from 'ttt-rest-service'
import {
ValidationError,
StatusError,
MimeError
} from 'ttt-rest-service/dist/errors'
// then look at one of example below
Fetcher and API Modules Metadata
Fetcher binds to the API Module metadata
API Module metadata is array of object which describe endpoints
Describe send data of endpoints with JSON Schema
API Module structure:
const authApiModule = [
{
// endpoint1
},
{
// endpoint2
},
]
Endpoint structure:
- method[string]
request method
- url[string]
request url. There is posibility to insert ID into url,
use ".../image/delete/{{id}}/"
to get ".../image/delete/id_102/"
- secure[boolean]
help variable
- roles[array]
help variable
- handler[string]
name of the class method that will be generated
- headers[object]
request headers
- schema[object]
JSON schema of the data send by the request
ApiModuleExample:
const authApiModule = [
{
method: 'POST',
url: '/auth/login',
secure: false,
handler: 'login',
roles: [],
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Credentials: 'include'
},
schema: {
type: 'object',
required: [ 'username', 'password' ],
properties: {
username: {
type: 'string',
minLength: 3
},
password: {
type: 'string',
minLength: 6
}
}
},
},
{
method: 'GET',
url: '/auth/logout/{{id}}',
secure: true,
handler: 'logout',
roles: [ 'user' ],
headers: {
Accept: 'application/json',
Credentials: 'include'
},
schema: {
// another JSON Schema
},
},
]
Example of usage
MimeParser && ResponseProcessor:
const { MimeParser, ResponseProcessor } = require("ttt-rest-service")
const mimeParserPairs = [
[ 'application/json', ( httpResponse ) => httpResponse.json() ]
]
const mimeParser = new MimeParser( mimeParserPairs )
const responseProcessor = new ResponseProcessor( mimeParser )
async function example() {
const request = await fetch( 'some-url.com/get-instance' )
const processedResponse = await responseProcessor.processResponse( request )
}
example()
Fetcher
const { FetcherFactory } = require('ttt-rest-service')
const authModule = [
{
method: 'POST',
url: '/auth/login',
secure: false,
handler: 'login',
roles: [],
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
schema: {
type: 'object',
required: [ 'username', 'password' ],
properties: {
username: {
type: 'string',
minLength: 3
},
password: {
type: 'string',
minLength: 6
}
},
},
},
];
const fetcherFactory = new FetcherFactory()
const fetcher = fetcherFactory.getFetcher(authModule)
const authToken = localStorage.get('authToken')
fetcher.onBeforeRequest(( requestParameters ) => {
if(requestParameters.secure && authToken === null) {
return true // prevent fetch
} else {
requestParameters.fetchParams.headers.Authorization = `Token ${ authToken }`
}
})
async function example() {
const sendData = {
username: 'username',
password: 'strong_password'
}
const request = await fetcher.request({ handlerName: 'login', data: sendData })
}
example()
Service
const { Service, fetcherFactory, mimeParser, responseProcessor } = require('ttt-rest-service')
const authModule = [
{
method: 'POST',
url: '/auth/login',
secure: false,
handler: 'login',
roles: [],
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
schema: {
type: 'object',
required: [ 'username', 'password' ],
properties: {
username: {
type: 'string',
minLength: 3
},
password: {
type: 'string',
minLength: 6
}
},
},
},
];
const fetcherFactory = new FetcherFactory();
const fetcher = fetcherFactory.getFetcher( authModule );
const mimeParserPairs = [
[ 'application/json', ( httpResponse ) => httpResponse.json() ]
];
const mimeParser = new MimeParser( mimeParserPairs );
const responseProcessor = new ResponseProcessor( mimeParser );
const service = new Service(fetcher, responseProcessor)
service.onBeforeRequest(({ handlerName, data, id}) => {
data.processedInBeforeRequest = true
return {
handlerName,
data,
id
}
})
service.onResponseHandled(({ handledResponse }) => {
handledResponse.parsedBody.processedInHook = true
})
async function exampleWithRequest() {
const request = await service.request({
handlerName: 'login',
data: {
username: 'username1',
password: 'very_very_strong'
}
})
}
async function exampleWithSpecifiedHandler() {
service.addHandler('login', authModule.schema)
service.login({
username: 'username1',
password: 'very_weak_password'
})
}
ServiceFactory
const { ServiceFactory, FetcherFactory, MimeParser, ResponseProcessor } = require('ttt-rest-service')
const API = {
auth: [
{
method: 'POST',
url: 'url.com/login/',
secure: false,
handlerName: 'login',
roles: [],
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
},
schema: {
//...
}
}
],
user: [
{
method: 'GET',
url: 'url.com/user/{{id}}',
secure: true,
handlerName: 'getUser',
roles: [],
headers: {
Accept: 'application/json'
},
schema: {
// ...
}
}
]
}
const fetcherFactory = new FetcherFactory();
const mimeParserPairs = [
[ 'application/json', ( httpResponse ) => httpResponse.json() ]
];
const mimeParser = new MimeParser( mimeParserPairs );
const responseProcessor = new ResponseProcessor( mimeParser );
const serviceFactory = new ServiceFactory( fetcherFactory, responseProcessor );
const services = serviceFactory.generateServices( API )
const authService = services.authService
const userService = services.userService
authService.login({
username: 'username1',
password: 'password1'
})
const userId = 'user_id_12343'
userService.getUser({
allInformation: true
}, userId)
Library API
FetcherFactory
getFetcher( apiModuleSchema )
apiModuleStructure:
const anApiModule = [
{
method: 'POST',
url: 'url.com/login/',
secure: false,
handlerName: 'login',
roles: [],
headers: {
// ...
},
schema: {
//...
}
},
{
// endpoint 2
// ...
}
]
Schema in endpoint metadata MUST BE IN JSON SCHEMA FORMAT
Fetcher
onBeforeFetch( callback )
Arg |
Type |
Default |
Description |
callback |
function |
() => false |
The function which will be called as a hook |
If you want prevent fetch execution, then your callback should return true
request( { handlerName, data = {}, id } )
Arg |
Type |
Default |
Description |
handlerName |
string |
undefined |
request name |
data |
object |
{} |
request payload |
id |
string |
undefined |
url id |
If there is no {{id}} template in metadata url, id will not be inserted
ResponseProcessor
constructor( mimeParser, invalidStatuses )
Arg |
Type |
Default |
Description |
mimeParser |
MimeParser |
undefined |
Helper class for parsing response body |
invalidStatuses |
array |
[] |
Array of statuses that will be considered invalid |
processResponse( httpResponse )
Arg |
Type |
Default |
Description |
httpResponse |
Response |
undefined |
Response that will be processed |
If response contains body functino returns,
{
parsedBody,
httpResponse,
}
else returns passed httpResponse
MimeParser
constructor( mimeParserPairs )
Arg |
Type |
Default |
Description |
mimeParserPairs |
array |
[] |
Pairs of mime-type and parser-function in mapable1 format |
Service
constructor(fetcher, responseProcessor, name)
Arg |
Type |
Default |
Description |
fetcher |
Fetcher |
null |
Instance of Fetcher |
responseProcessor |
ResponseProcessor |
null |
Instance of ResponseProcessor |
name |
string |
undefined |
Service name |
request({ handlerName, data, id })
Arg |
Type |
Default |
Description |
handlerName |
string |
undefined |
Name of endpoint specified in endpoint metadata by handler property |
data |
object |
{} |
Request send data |
id |
string |
undefined |
A string which will replace {{id}} template in url |
addHandler( handlerName, dataSchema )
Arg |
Type |
Default |
Description |
handlerName |
string |
undefined |
The name of property which will be set on a service instance |
dataSchema |
object |
undefined |
The data schema of request send data |
onBeforeRequest( callback )
Arg |
Type |
Default |
Description |
callback |
function |
(val) => val |
The function which will be called as a hook |
onResponseHandled( callback )
Arg |
Type |
Default |
Description |
callback |
function |
(val) => val |
The function which will be called as a hook |
onBeforeFetch( callback )
Arg |
Type |
Default |
Description |
callback |
function |
(val) => val |
The function which will be called as a hook |
ServiceFactory
generateServices( api )
Arg |
Type |
Default |
Description |
api |
object |
undefined |
An object that describe API modules; |
generateService( apiModuleName, apiModuleSchema )
Arg |
Type |
Default |
Description |
apiModuleName |
string |
undefined |
Name of module which will be set as name of a service |
apiModuleSchema |
object |
undefined |
The metadata of endpoint |
-
mapable means array which can be used for creating of map ↩