Просмотр исходного кода

:sparkles: swagger docs | lots of comments | refactoring around plugins

master
j 5 лет назад
Родитель
Сommit
593c94f379

+ 13
- 0
backend/config/dev.js Просмотреть файл

1
+const config = {
2
+    /** Server info */
3
+    host: 'localhost',
4
+    port: 3001,
5
+
6
+    /** URL preceding endpoints */
7
+    apiBase: 'api',
8
+
9
+    /** Uncomment for cross-origin */
10
+    corsSupported: false
11
+}
12
+
13
+export { config }

+ 944
- 6
backend/package-lock.json
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 4
- 1
backend/package.json Просмотреть файл

10
   "author": "TOJ",
10
   "author": "TOJ",
11
   "license": "UNLICENSED",
11
   "license": "UNLICENSED",
12
   "dependencies": {
12
   "dependencies": {
13
-    "@hapi/hapi": "^20.1.3"
13
+    "@hapi/hapi": "^20.1.3",
14
+    "hapi-swaggered": "^3.0.2",
15
+    "hapi-swaggered-ui": "^3.1.0",
16
+    "joi": "^13.7.0"
14
   },
17
   },
15
   "devDependencies": {
18
   "devDependencies": {
16
     "nodemon": "^2.0.7"
19
     "nodemon": "^2.0.7"

+ 28
- 0
backend/src/docs.js Просмотреть файл

1
+import hapiSwaggered from 'hapi-swaggered'
2
+import hapiSwaggeredUI from 'hapi-swaggered-ui'
3
+
4
+// ?: hapi-swaggered deps
5
+import vision from 'vision'
6
+import inert from 'inert'
7
+
8
+const swaggered = {
9
+    plugin: hapiSwaggered,
10
+    options: {},
11
+    info: {
12
+        title: 'EXAMPLE',
13
+        descrioption: 'just a test',
14
+        version: '1.0.0'
15
+    }
16
+}
17
+
18
+const swaggeredUI = {
19
+    plugin: hapiSwaggeredUI,
20
+    options: {
21
+        path: '/docs',
22
+        swaggerOptions: {
23
+            validatorUrl: null
24
+        },
25
+    }
26
+}
27
+
28
+export default [ vision, inert, swaggered, swaggeredUI ]

+ 6
- 4
backend/src/handlers/index.js Просмотреть файл

1
-import { profile } from './profile.js'
2
-
1
+/** 
2
+ * Your default handlers
3
+ * NOT to be confused with per
4
+ * plugin HTTP handlers
5
+ */
3
 const handlers = {
6
 const handlers = {
4
     default: {
7
     default: {
5
         get: (request, h) => {
8
         get: (request, h) => {
9
                 data: {}
12
                 data: {}
10
             }
13
             }
11
         }
14
         }
12
-    },
13
-    profile
15
+    }
14
 }
16
 }
15
 
17
 
16
 export { handlers }
18
 export { handlers }

+ 19
- 11
backend/src/index.js Просмотреть файл

1
 import Hapi from '@hapi/hapi'
1
 import Hapi from '@hapi/hapi'
2
 
2
 
3
-import { routes } from './routes.js'
3
+import { routes } from './routes/index.js'
4
 import { plugins } from './plugins/index.js'
4
 import { plugins } from './plugins/index.js'
5
 
5
 
6
+import docs from './docs.js'
7
+
8
+import { config } from '../config/dev.js'
9
+
6
 const server = Hapi.server({
10
 const server = Hapi.server({
7
-    port: 3001,
8
-    host: 'localhost',
9
-    routes: { cors: true }
10
-});
11
+    port: config.port,
12
+    host: config.host,
13
+    routes: { 
14
+        cors: config.corsSupported
15
+    }
16
+})
11
 
17
 
12
 const init = async () => {
18
 const init = async () => {
13
     try {
19
     try {
15
 
21
 
16
         for(const plugin of plugins) {
22
         for(const plugin of plugins) {
17
             await server.register(plugin, {
23
             await server.register(plugin, {
18
-                routes: { prefix: '/plugins' }
24
+                routes: { prefix: `/${config.apiBase}` }
19
             })
25
             })
20
         }
26
         }
27
+        
28
+        await server.register(docs)
21
 
29
 
22
         await server.start();
30
         await server.start();
23
-        console.log('Server running on %s', server.info.uri);
31
+        console.log('\n[SIIMEE API] Server running on %s', server.info.uri)
24
     }
32
     }
25
 
33
 
26
     catch(err) {
34
     catch(err) {
27
-        console.error(err);
35
+        console.error(err)
28
     }
36
     }
29
 
37
 
30
 };
38
 };
31
 
39
 
32
 process.on('unhandledRejection', (err) => {
40
 process.on('unhandledRejection', (err) => {
33
-    console.log(err);
34
-    process.exit(1);
35
-});
41
+    console.log(err)
42
+    process.exit(1)
43
+})
36
 
44
 
37
 init()
45
 init()
38
 
46
 

+ 1
- 1
backend/src/plugins/index.js Просмотреть файл

1
-import { profilePlugin } from './profile.js'
1
+import { profilePlugin } from './profile/index.js'
2
 import { testPlugin } from './test.js'
2
 import { testPlugin } from './test.js'
3
 
3
 
4
 const plugins = [ testPlugin, profilePlugin ]
4
 const plugins = [ testPlugin, profilePlugin ]

+ 0
- 15
backend/src/plugins/profile.js Просмотреть файл

1
-import { handlers } from '../handlers/index.js'
2
-
3
-const profilePlugin = {
4
-    name: 'profile-plugin',
5
-    version: '1.0.0',
6
-    register: async (server, options) => {
7
-        server.route({
8
-            method: 'GET',
9
-            path: '/profile',
10
-            handler: handlers.profile.get
11
-        })
12
-    }
13
-}
14
-
15
-export { profilePlugin }

backend/src/handlers/profile.js → backend/src/plugins/profile/handlers.js Просмотреть файл

1
 // https://github.com/connor11528/task-app-backend/blob/master/src/api/index.js
1
 // https://github.com/connor11528/task-app-backend/blob/master/src/api/index.js
2
 
2
 
3
-const profile = {
3
+const handlers = {
4
     get: (request, h) => {
4
     get: (request, h) => {
5
         try {
5
         try {
6
-            console.log('get handler for profile');
7
-
8
-            // You have to return SOMETHING
9
             return { 
6
             return { 
10
                 ok: true,
7
                 ok: true,
11
                 handler: 'profile',
8
                 handler: 'profile',
12
-                data: { name: 'Chuck Charles' },
9
+                data: { name: request.params.name },
13
             }
10
             }
11
+        }
14
 
12
 
15
-        } 
16
         catch (err) {
13
         catch (err) {
17
             //   Boom.badImplementation(err);
14
             //   Boom.badImplementation(err);
18
         }
15
         }
19
     }
16
     }
20
 }
17
 }
21
 
18
 
22
-export { profile }
19
+export { handlers }

+ 44
- 0
backend/src/plugins/profile/index.js Просмотреть файл

1
+import { responses } from './responses.js'
2
+
3
+/**
4
+ * Swagger Descriptions
5
+ * Keys should match HTTP methods
6
+ * GET, PATCH, PUT, DELETE
7
+ * @param {string} description: Describe the endpoint
8
+ * @param {string} notes: What to expect as a return
9
+ */
10
+const descriptions = {
11
+    'GET': {
12
+        description: 'Profile endpoint returns junk',
13
+        notes: 'There\'s a lot we don\'nt know about yet'
14
+    }
15
+}
16
+
17
+/** Profile plugin ready for export */
18
+const profilePlugin = {
19
+    name: 'profile-plugin',
20
+    version: '1.0.0',
21
+
22
+    /**
23
+     * Register each HTTP response type
24
+     * Adds Swagger descriptions, response validations,
25
+     * and path validations all in one
26
+     * @param {object} responses - configs for all responses
27
+     */
28
+    register: async (server, options) => { 
29
+        Object.values(responses).forEach(res => {
30
+            
31
+            /** 
32
+             * Copy our response config and
33
+             * sprinkle endpoint docs
34
+             */
35
+            res.options = { 
36
+                ...descriptions[res.method],
37
+                ...res.options
38
+            }
39
+            server.route(res)
40
+        })
41
+    }
42
+}
43
+
44
+export { profilePlugin }

+ 22
- 0
backend/src/plugins/profile/responses.js Просмотреть файл

1
+import { validators } from './validators.js'
2
+import { handlers } from './handlers.js'
3
+
4
+const responses = {
5
+    get: {
6
+        method: 'GET',
7
+        path: '/profile/{name}',
8
+        handler: handlers.get,
9
+        options: { 
10
+            tags: ['api'],
11
+            validate: {
12
+                params: validators.params
13
+            },
14
+            response: {
15
+                schema: validators.resSchema,
16
+                failAction: 'log'
17
+            }
18
+        }
19
+    }
20
+}
21
+
22
+export { responses }

+ 15
- 0
backend/src/plugins/profile/validators.js Просмотреть файл

1
+import Joi from 'Joi'
2
+
3
+const validators = {
4
+    params: Joi.object({
5
+        name: Joi.string().min(3).max(11)
6
+    })
7
+}
8
+
9
+validators.resSchema = Joi.object({
10
+    ok: Joi.bool(),
11
+    handler: Joi.string(),
12
+    data: validators.params
13
+})
14
+
15
+export { validators }

backend/src/routes.js → backend/src/routes/index.js Просмотреть файл

1
-import { handlers } from './handlers/index.js'
1
+import { handlers } from '../handlers/index.js'
2
 
2
 
3
 const routes = [
3
 const routes = [
4
     {
4
     {

Загрузка…
Отмена
Сохранить