Last active
March 8, 2016 14:37
-
-
Save kvendrik/9fbe775e1644a624589f to your computer and use it in GitHub Desktop.
API URL parser
This file contains hidden or 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
| const endpoints = { | |
| user: { | |
| get: { | |
| href: "https://api.github.com/user/:id/:name", | |
| templated: true | |
| } | |
| }, | |
| articles: { | |
| get: { | |
| href: "https://api.github.com/articles" | |
| } | |
| }, | |
| article: { | |
| get: { | |
| href: "https://api.github.com/article/:id", | |
| templated: true | |
| }, | |
| post: { | |
| href: "https://api.github.com/article", | |
| params: { | |
| name: "String", | |
| date: "Date", | |
| country: { | |
| state: "String", | |
| name: { | |
| first: "String", | |
| last: { | |
| type: 'String', | |
| optional: true | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| // const apiUrls = new UrlParser(endpoints); | |
| // apiUrls.user.get({ id: 2, name: "matti" }, function(err, res){ | |
| // console.log('ohhjaaa'); | |
| // }); | |
| // apiUrls.article.post({ | |
| // name: 'How to be Awesome by Matti', | |
| // date: new Date(), | |
| // country: 'NY' | |
| // }, function(err, res){ | |
| // console.log('ohhjaaa'); | |
| // }); | |
| let parser = new SchemaParser(endpoints.article.post.params) | |
| parser.checkParamsValid({ | |
| name: 'How to be Awesome by Matti', | |
| date: new Date(), | |
| country: { state: 'NY', name: { first: 'Matti' } } | |
| }); |
This file contains hidden or 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
| class SchemaParser { | |
| typeOptions = ["String", "Number", "Date", "Array", "Object", "Boolean"]; | |
| constructor(schema){ | |
| this._schema = schema; | |
| } | |
| _getValueType(value){ | |
| var type = {}.toString.call(value); | |
| return type.match(/\s(\w+)/)[1]; | |
| } | |
| checkParamsValid(params){ | |
| let schema = this._schema, | |
| self = this; | |
| let checkSchemaObject = function(schemaObj, paramsObj){ | |
| //loop all properties in object | |
| for(let key in schemaObj){ | |
| //get the schema value, the actual value and the schema type | |
| let schemaVal = schemaObj[key], | |
| paramsVal = paramsObj[key], | |
| objType = self._getValueType(schemaVal); | |
| //if not in given params and not optional, throw error | |
| if(typeof paramsVal === 'undefined' && schemaVal.optional !== true){ | |
| throw new Error('Param "'+key+'" is required'); | |
| } | |
| //if its an object and has a type option or is a string | |
| //its a schema object/string | |
| var isSchema = (objType === 'Object' && typeof schemaVal.type !== 'undefined'); | |
| if(objType === 'String') isSchema = true; | |
| if(isSchema){ | |
| let validType = (objType === 'String' ? schemaVal : schemaVal.type), | |
| actualType = self._getValueType(paramsVal); | |
| //if the actual type does not match the type | |
| //it should be | |
| if(actualType !== validType){ | |
| if(actualType === 'Undefined' && schemaVal.optional === true){ | |
| //dont throw an error as the value is undefined and optional | |
| continue; | |
| } | |
| //value is invalid | |
| throw new Error('Param "'+key+'" should be of type '+validType); | |
| } | |
| } else { | |
| //if its not an object and has no type property and is not a string | |
| //its a custom object | |
| checkSchemaObject(schemaVal, paramsVal); | |
| } | |
| } | |
| }; | |
| checkSchemaObject(schema, params); | |
| } | |
| } |
This file contains hidden or 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
| class UrlParser { | |
| constructor(endpoints){ | |
| this._storeEndpoints(endpoints); | |
| } | |
| _publicsMethods = { | |
| get: function(params, callback, obj){ | |
| //get endpoint details | |
| let details = obj._get; | |
| //get parsed endpoint url | |
| let endpointUrl = details.templated ? this._parseEndpointStr(details._cleanHref, params) : details.href; | |
| console.log(endpointUrl); | |
| }, | |
| post: function(params, callback, obj){ | |
| //get endpoint details | |
| let details = obj._post; | |
| let valid = this._checkParamsSchema(details.params, params); | |
| console.log(endpointUrl); | |
| } | |
| } | |
| _storeEndpoints(endpoints){ | |
| //loop endpoints | |
| for(let name in endpoints){ | |
| let details = endpoints[name]; | |
| //loop request methods | |
| for(let reqMethod in details){ | |
| let reqMethodDetails = details[reqMethod]; | |
| reqMethodDetails._cleanHref = reqMethodDetails.href.replace(/http(s)?\:\/\//, ''); | |
| //save details to different location in object | |
| details['_'+reqMethod] = reqMethodDetails; | |
| //replace method in object with function to use the endpoint | |
| details[reqMethod] = (params, callback) => this._publicsMethods[reqMethod].apply(this, [params, callback, details]); | |
| } | |
| this[name] = details; | |
| } | |
| } | |
| _parseEndpointStr(endpoint, givenParams){ | |
| let endpointParamNames = this._getUrlEndpointParamNames(endpoint); | |
| //check if all required params are provided | |
| endpointParamNames.forEach(function(name){ | |
| if(typeof givenParams[name] === 'undefined'){ | |
| //throw error | |
| throw new Error('Param "'+name+'" is required for endpoint '+endpoint); | |
| } | |
| }); | |
| //parse endpoint URL | |
| for(let name in givenParams){ | |
| let val = givenParams[name]; | |
| endpoint = endpoint.replace(':'+name, val); | |
| } | |
| return endpoint; | |
| } | |
| _getUrlEndpointParamNames(endpoint, params){ | |
| let matches = endpoint.match(/\:([^\/\:]+)/g); | |
| matches = matches.map(function(match){ | |
| return match.replace(/\:/g, ''); | |
| }); | |
| return matches | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment