REST API Meteor.js Wrapper
This package should enable you to wrap any general REST API so that it can be easily called from the Meteor server, if the provider has a REST-like interface.
It was written with an SMS API in mind, but should work well with any HTTP API that you wish to call from the server.
Installing REST API Wrapper package
Use following command to install the meteor package.
$ meteor add appworkshop:rest-api-wrapper
Configuring
All settings are specified in your settings.json file, under appworkshop.restendpoints e.g.
... , appworkshop: { restendpoints: [ { actionName: "sendSMS", httpMethod: "post", endpoint: "https://api.clicksend.com/rest/v2/send.json", auth: { username: "myClickSendUsername", password: "myClickSendAPIKey" }, additionalHeaders: { "Authorization-Token": "123456789", "Other-Header-Key": "Other-Header-Value" }, additionalFormData: { method: "rest", customstring: "ClickSend will pass this back in the response"} } } ], defaultTimeout: 2000 }, public: {...},
You could then initialise the API:
var smsFunctionLibrary = new RestEndpoints();
And use it:
var result = smsFunctionLibrary.sendSMS({ to:"+61411111111", message:"This is the message", senderid:"MyCompany" });
Or asynchronously, with a callback:
var functionLibrary = new RestEndpoints(); var smsResult = functionLibrary.sendSMS( { to: "+61411111111", message: "This is the message", senderid: "MyCompany" }, function (error, result) { // "invalid credentials"; result.statusCode = 401 } );
If you don't want to provide settings in the Meteor settings.json, you can do so at runtime:
var smsFunctionLibrary = new RestEndpoints(restEndpointsArray);
This is literally a convenience wrapper around Meteor's HTTP.call
.
The idea is that you document the API's details in JSON. So
although it was written with SMS in mind, it should work nicely for twitter, google translate ... you name it.
Full REST Example
Here's how you can wrap a complete API.
1 var apiSettings = [ 2 { 3 actionName: "insertPost", 4 httpMethod: "post", 5 endpoint: "http://jsonplaceholder.typicode.com/posts", 6 auth: { 7 username: "myUsername", 8 password: "myPassword" 9 }, 10 additionalHeaders: { 11 "Authorization-Token": "123456789", 12 "Other-Header-Key": "Other-Header-Value" 13 }, 14 additionalFormData: { 15 method: "rest", 16 customstring: "CustomString" 17 } 18 }, 19 { 20 actionName: "getAllPosts", 21 httpMethod: "get", 22 endpoint: "http://jsonplaceholder.typicode.com/posts", 23 auth: { 24 username: "myDummyUsername", 25 password: "myDummyAPIKey" 26 } 27 }, 28 { 29 actionName: "getSinglePostByID", 30 httpMethod: "get", 31 endpoint: "http://jsonplaceholder.typicode.com/posts", 32 auth: { 33 username: "myClickSendUsername", 34 password: "myClickSendAPIKey" 35 } 36 }, 37 { 38 actionName: "getCommentsForPostID", 39 httpMethod: "get", 40 endpoint: "http://jsonplaceholder.typicode.com/comments", 41 auth: { 42 username: "myClickSendUsername", 43 password: "myClickSendAPIKey" 44 } 45 }, 46 { 47 actionName: "getToDosForUser", 48 httpMethod: "get", 49 endpoint: "http://jsonplaceholder.typicode.com/users", 50 auth: { 51 username: "myClickSendUsername", 52 password: "myClickSendAPIKey" 53 } 54 }, 55 { 56 actionName: "getBasecampProjects", 57 httpMethod: "get", 58 endpoint: "https://3.basecampapi.com", 59 additionalHeaders: { 60 "User-Agent": "Company Name (http://your.company.url)", 61 "Authorization": "Bearer your-user-access-token-here" 62 } 63 }, 64 { 65 actionName: "getAllTodosForProject", 66 httpMethod: "get", 67 endpoint: "https://3.basecampapi.com", 68 additionalHeaders: { 69 "User-Agent": "Company Name (http://your.company.url)", 70 "Authorization": "Bearer your-user-access-token-here" 71 } 72 }, 73 { 74 actionName: "updateSinglePostByID", 75 httpMethod: "patch", 76 endpoint: "http://jsonplaceholder.typicode.com/posts", 77 auth: { 78 username: "myUsername", 79 password: "myPassword" 80 }, 81 }, 82 { 83 actionName: "replaceSinglePostByID", 84 httpMethod: "patch", 85 endpoint: "http://jsonplaceholder.typicode.com/posts", 86 auth: { 87 username: "myUsername", 88 password: "myPassword" 89 }, 90 }, 91 { 92 actionName: "deleteSinglePostByID", 93 httpMethod: "delete", 94 endpoint: "http://jsonplaceholder.typicode.com/posts", 95 auth: { 96 username: "myUsername", 97 password: "myPassword" 98 }, 99 }, 100 { 101 actionName: "sendDataInsteadOfParams", 102 httpMethod: "post", 103 endpoint: "http://jsonplaceholder.typicode.com/posts", 104 auth: { 105 username: "myUsername", 106 password: "myPassword" 107 }, 108 additionalHeaders: { 109 "Authorization-Token": "123456789", 110 "Other-Header-Key": "Other-Header-Value" 111 } 112 } 113 ]; 114 115 // now initialize our API wrapper 116 var functionLibrary = new RestEndpoints(apiSettings); 117 118 // now each of the actionName properties is accessible as a function. 119 120 // get all posts 121 var allPosts = functionLibrary.getAllPosts(); 122 123 // get one post object by ID 124 // Note the use of the special _ID_ parameter; this gets appended to the endpoint URL. 125 var onePost = functionLibrary.getSinglePostByID({_ID_: 1}); 126 127 // get a nested property of a user by ID 128 var allTodosForUser = functionLibrary.getToDosForUser({_ID_: '1/todos'}); 129 130 // insert a new post 131 var postResult = functionLibrary.insertPost({ 132 title: 'foo', 133 body: 'bar', 134 userId: 1 135 }); 136 137 // update a post 138 var newPost = functionLibrary.updateSinglePostByID({_ID_: 1, 'title': 'cheese'}); 139 140 // replace a post completely 141 var newPost = functionLibrary.replaceSinglePostByID({ 142 _ID_: 1, 143 id: 1, 144 title: 'foo', 145 body: 'chocolate', 146 userId: 1 147 }); 148 149 // delete a post 150 var result = functionLibrary.deleteSinglePostByID({_ID_: 1}); 151 152 // append to the url 153 // the following will build the endpoint to 154 // https://3.basecampapi.com/999999999/projects.json 155 var allProjects = functionLibrary.getBasecampProjects({ 156 _ID_: 999999999, 157 _APPEND_TO_URL_: "projects.json" 158 }); 159 160 // completely replace the endpoint url 161 var getBasecampTodos = functionLibrary.getAllTodosForProject({ 162 _OVERRIDE_URL_: "https://3.basecampapi.com/999999999/buckets/1/todolists/3/todos.json" 163 }); 164 165 // send given params as data: {} instead 166 var params = { 167 "title": "foo", 168 "body": "bar", 169 "userId": 1 170 }; 171 172 var sendDataInsteadOfParams = functionLibrary.sendDataInsteadOfParams({_PARAMS_TO_DATA_: params});
TODO:
- oauth
- create a catalogue of APIs specified this way.