├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── demo ├── .eslintignore ├── .eslintrc ├── EmberQL.ts ├── client │ ├── App.tsx │ ├── components │ │ ├── Contributing.tsx │ │ ├── ContributingStyles.css │ │ ├── DocsContainer.tsx │ │ ├── DocsStyles.css │ │ ├── EmberQL.tsx │ │ ├── EmberQLStyles.css │ │ ├── Feature.tsx │ │ ├── Features.tsx │ │ ├── FeaturesStyles.css │ │ ├── LandingContainer.tsx │ │ ├── NavStyles.css │ │ ├── Navbar.tsx │ │ ├── Team.tsx │ │ ├── TeamMember.tsx │ │ ├── TeamStyles.css │ │ ├── WhyReason.tsx │ │ ├── WhyStyles.css │ │ ├── WhyWeExist.tsx │ │ ├── assets │ │ │ ├── BloatedA.png │ │ │ ├── buttons.png │ │ │ ├── cristian.png │ │ │ ├── favicon.ico │ │ │ ├── graphql.png │ │ │ ├── heart.png │ │ │ ├── icon.png │ │ │ ├── manju.png │ │ │ ├── mike.png │ │ │ ├── ram.png │ │ │ ├── redis.png │ │ │ ├── shield.png │ │ │ └── tyler.png │ │ └── demo-components │ │ │ ├── DemoContainer.tsx │ │ │ ├── GraphContainer.tsx │ │ │ └── QueryContainer.tsx │ ├── index.tsx │ └── styles.css ├── d.ts ├── index.html ├── package-lock.json ├── package.json ├── server │ ├── models │ │ └── db.js │ ├── schema │ │ └── schema.ts │ └── server.ts ├── tsconfig.json └── webpack.config.js └── src ├── EmberQL.js ├── EmberQL.ts ├── README.md ├── package-lock.json └── package.json /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-vendored=true 2 | *.ts linguist-vendored=false 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | compiledTS/ 44 | build/ 45 | 46 | # TypeScript v1 declaration files 47 | typings/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | 55 | # Optional eslint cache 56 | .eslintcache 57 | 58 | # Microbundle cache 59 | .rpt2_cache/ 60 | .rts2_cache_cjs/ 61 | .rts2_cache_es/ 62 | .rts2_cache_umd/ 63 | 64 | # Optional REPL history 65 | .node_repl_history 66 | 67 | # Output of 'npm pack' 68 | *.tgz 69 | 70 | # Yarn Integrity file 71 | .yarn-integrity 72 | 73 | # dotenv environment variables file 74 | .env 75 | .env.test 76 | 77 | # parcel-bundler cache (https://parceljs.org/) 78 | .cache 79 | 80 | # Next.js build output 81 | .next 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Zip files 109 | *.zip -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 OSLabs Beta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EmberQL 2 | 3 |
{description}
21 |
14 |
15 |
19 |
20 |
25 | EmberQL is an intuitive, lightweight Node module that facilitates 26 | caching data from GraphQL queries, and implements a dynamic data 27 | persistence system that monitors the status of the primary database 28 | and modifies cache invalidation accordingly. 29 |
30 |38 | {' '} 39 | Decrease the time it takes for your users to fetch data from your 40 | database by up to one hundred fold. Research shows that even a second 41 | of latency will drastically increase bounce rates on your application. 42 | Additionally, depending on the specifications or hosting of your 43 | database, too many simultaneous queries can cause timeouts to occur. 44 | Using EmberQL, there is no need to gamble with forcing your users to 45 | make redundant queries to your database. 46 |
47 |50 | {' '} 51 | EmberQL incorporates a smart "heartbeat" feature that will monitor 52 | your database in real time and halt cache invalidation when it detects 53 | downtime. This is done by periodically increasing the time to live of 54 | cached data, and as soon as the database comes back online cached 55 | items will revert to being evicted normally. The heartbeat will 56 | communicate relevant information about the cache and database to the 57 | developer in the server console.{' '} 58 |
59 |65 | {' '} 66 | In the event of your database going down, the most relevant 67 | information users are querying will be available in the in-memory 68 | database and thus available to users. With EmberQL, there is no need 69 | for your clients to notice when your database isn't running. You can 70 | rest assured that your application will have fault tolerance after 71 | installing the module.{' '} 72 |
73 |80 | Install the EmberQL module into your Node.js application by running 81 | the command npm install emberql. Your application must have GraphQL 82 | and as a dependency, and you will need to define your schema so that 83 | EmberQL can make use of it. You will also need Redis as a dependency 84 | to access the Redis functions (createClient, connect, on, etc.) and 85 | you will need to either run a Redis server on your machine locally or 86 | utilize AWS Elasticache to run a Redis server.{' '} 87 |
88 |93 | After installing, the module can be easily configured by making a few 94 | small additions to your server file.{' '} 95 |
96 |97 | The EmberQL class will take your GraphQL schema and your Redis cache 98 | instance as arguments: 99 |
100 |101 |109 |102 |108 |103 | const Ember ={' '} 104 | new EmberQL(schema, 105 | redisCache);{'\n'} 106 |
107 |
110 | Any request sent to '/graphql' should be routed through the 111 | handleQuery middleware: 112 |
113 |114 |129 |115 |128 |116 | app.use('/graphql', 117 | Ember.handleQuery,{' '} 118 | 119 | (req, res) => 120 | {' '} 121 | {'{'} 122 | {'\n'} 123 | {' '}res.status(202 124 | ).json(res.locals.data);{'\n'} 125 | {'}'});{'\n'} 126 |
127 |
130 | To clear the Redis cache, send a request to the '/clearCache' endpoint 131 | and route it through the EmberQL clearCache method: 132 |
133 |134 |149 |135 |148 |136 | app.use('/clearCache', 137 | Ember.clearCache,{' '} 138 | 139 | (req, res) => 140 | {' '} 141 | {'{'} 142 | {'\n'} 143 | {' '}res.sendStatus(202); 144 | {'\n'} 145 | {'}'});{'\n'} 146 |
147 |
150 | To set up the heartbeat, simply save the heartbeat property of the new 151 | EmberQL instance you just declared to a new variable. Then use the 152 | setInterval method and an interval of your choice to assign the 153 | frequency you would like the heartbeat to check your database: 154 |
155 |156 |170 |157 |169 |158 | const EmberHeartbeat = Ember.heartbeat;{'\n'} 159 | {'\n'}setInterval( 160 | 161 | () => 162 | {' '} 163 | {'{'} 164 | {'\n'} 165 | {' '}EmberHeartbeat();{'\n'} 166 | {'}'}, 3000);{'\n'} 167 |
168 |
174 | Data normalization for Redis caching is currently in our development 175 | pipeline. The prototype utilizes a recursive function to parse the 176 | GraphQL AST and transform queries into key value pairs leveraging 177 | hashing to optimize memory.{' '} 178 |
179 |184 | 185 | Cristian De Los Rios 186 | {' '} 187 | |{' '} 188 | 189 | Manjunath Ajjappa Pattanashetty 190 | {' '} 191 | |{' '} 192 | 193 | Mike Masatsugu 194 | {' '} 195 | |{' '} 196 | 197 | Ram Marimuthu 198 | {' '} 199 | |{' '} 200 | 201 | Tyler Pohn 202 | 203 |
204 |{description}
13 |{description}
14 |