Quellcode durchsuchen

:fire: complete reorg of backend

master
j vor 5 Jahren
Ursprung
Commit
31b8854455

+ 1
- 3
backend/config/dev.js Datei anzeigen

@@ -1,4 +1,4 @@
1
-const config = {
1
+module.exports = {
2 2
     /** Server info */
3 3
     host: 'localhost',
4 4
     port: 3001,
@@ -14,5 +14,3 @@ const config = {
14 14
     corsSupported: false
15 15
 }
16 16
 
17
-export { config }
18
-

+ 410
- 1338
backend/package-lock.json
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 5
- 6
backend/package.json Datei anzeigen

@@ -11,17 +11,16 @@
11 11
   "license": "UNLICENSED",
12 12
   "dependencies": {
13 13
     "@hapi/hapi": "^20.1.3",
14
+    "@hapi/inert": "^6.0.3",
15
+    "@hapi/vision": "^6.0.1",
14 16
     "@hapipal/schwifty": "^6.0.0",
15
-    "hapi-sequelizejs": "^4.4.0",
16
-    "hapi-swaggered": "^3.0.2",
17
-    "hapi-swaggered-ui": "^3.1.0",
18
-    "joi": "^13.7.0",
17
+    "hapi-swagger": "^14.1.3",
18
+    "joi": "^17.4.0",
19 19
     "knex": "^0.21.19",
20 20
     "mysql": "^2.18.1",
21 21
     "objection": "^2.2.15"
22 22
   },
23 23
   "devDependencies": {
24 24
     "nodemon": "^2.0.7"
25
-  },
26
-  "type": "module"
25
+  }
27 26
 }

+ 0
- 29
backend/src/docs.js Datei anzeigen

@@ -1,29 +0,0 @@
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
-const docs = [ vision, inert, swaggered, swaggeredUI ]
28
-
29
-export { docs }

+ 0
- 18
backend/src/handlers/index.js Datei anzeigen

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

+ 46
- 96
backend/src/index.js Datei anzeigen

@@ -1,101 +1,51 @@
1
-import Hapi from '@hapi/hapi'
2
-import Schwifty from '@hapipal/schwifty'
3
-
4
-import { config } from '../config/dev.js'
5
-
6
-import { routes } from './routes/index.js'
7
-import { plugins } from './plugins/index.js'
8
-import { docs } from './docs.js'
9
-
10
-import Joi from 'joi'
11
-
12
-const server = Hapi.server({
13
-    port: config.port,
14
-    host: config.host,
15
-    routes: {
16
-        cors: config.corsSupported
17
-    }
18
-})
19
-
20
-const dbConnection = {
21
-    host : config.host,
22
-    user : 'root',
23
-    password : 'root',
24
-    database : config.db
25
-}
26
-
27
-const init = async () => {
28
-    try {
29
-        routes.forEach(route => server.route(route))
30
-
31
-        for(const plugin of plugins) {
32
-            await server.register(plugin, {
33
-                routes: { prefix: `/${config.apiBase}` }
34
-            })
1
+const Hapi = require('@hapi/hapi');
2
+const Inert = require('@hapi/inert');
3
+const Vision = require('@hapi/vision');
4
+const Schwifty = require('@hapipal/schwifty');
5
+const HapiSwagger = require('hapi-swagger');
6
+
7
+const config = require('../config/dev');
8
+
9
+const AppPlugin = require('./plugins');
10
+
11
+(async () => {
12
+    const server = Hapi.server({
13
+        port: config.port,
14
+        host: config.host,
15
+        routes: {
16
+            cors: config.corsSupported
35 17
         }
36
-
37
-        await server.register(docs)
38
-
39
-        /** Register the database connection */
40
-        console.log(`\n[SIIMEE API] Database: ${config.db} | Attempting to connect on port ${config.dbPort}...`)
41
-        await server.register({
42
-            plugin: Schwifty,
18
+    })
19
+
20
+    await server.register([ 
21
+        AppPlugin,
22
+        // Documentaion deps
23
+        Inert,
24
+        Vision,
25
+        {
26
+            plugin: HapiSwagger,
43 27
             options: {
44
-                knex: { client: config.dbDialect, connection: dbConnection }
28
+                info: { title: 'Test API Documentation' }
45 29
             }
46
-        })
47
-        console.log(`[SIIMEE API] Database: ${config.db} | Connection has been established on port ${config.dbPort}!`)
48
-
49
-
50
-
51
-
52
-
53
-        server.registerModel(
54
-            class Dog extends Schwifty.Model {
55
-                static tableName = 'Dog'
56
-                static joiSchema = Joi.object({
57
-                    id: Joi.number(),
58
-                    name: Joi.string()
59
-                })
30
+        },
31
+        // DB and model connectors
32
+        {
33
+            plugin: Schwifty,
34
+            options: {
35
+                knex: {
36
+                    client: config.dbDialect,
37
+                    useNullAsDefault: true,
38
+                    connection: {
39
+                        host : config.host,
40
+                        user : 'root',
41
+                        password : 'root',
42
+                        database : config.db
43
+                    }
44
+                }
60 45
             }
61
-        )
62
-
63
-
64
-        /** Lift Off! */
65
-        await server.initialize()
66
-        
67
-        const knex = server.knex()
68
-        // console.log(knex)
69
-        await knex.schema.createTable('Dog', (table) => {
70
-            table.increments('id').primary()
71
-            table.string('name')
72
-        })
73
-    
74
-        // ... then add some records ...
75
-    
76
-        const { Dog } = server.models()
77
-    
78
-        await Promise.all([
79
-            Dog.query().insert({ name: 'Guinness' }),
80
-            Dog.query().insert({ name: 'Sully' }),
81
-            Dog.query().insert({ name: 'Ren' })
82
-        ])
83
-
84
-        await server.start()
85
-        console.log('\n[SIIMEE API] Server running on %s', server.info.uri)
86
-    }
87
-
88
-    catch(err) {
89
-        console.error(err)
90
-    }
91
-
92
-};
93
-
94
-process.on('unhandledRejection', (err) => {
95
-    console.log(err)
96
-    process.exit(1)
97
-})
98
-
99
-init()
46
+        }
47
+    ])
100 48
 
101
-export default server
49
+    await server.start()
50
+    console.log(`Ready to go! See ${server.info.uri}`)
51
+})();

+ 0
- 0
backend/src/models/user.js Datei anzeigen


+ 14
- 4
backend/src/plugins/index.js Datei anzeigen

@@ -1,6 +1,16 @@
1
-import { profilePlugin } from './profile/index.js'
2
-import { testPlugin } from './test.js'
1
+const config = require('../../config/dev');
3 2
 
4
-const plugins = [ testPlugin, profilePlugin ]
3
+const UserPlugin = require('./user');
4
+const TestPlugin = require('./test');
5 5
 
6
-export { plugins }
6
+const pluginOptions = {
7
+    routes: { prefix: `/${config.apiBase}` }
8
+}
9
+
10
+module.exports = {
11
+    name: 'my-app-plugin',
12
+    register: async (server, options) => {
13
+        await server.register(TestPlugin, pluginOptions)
14
+        await server.register(UserPlugin, pluginOptions)
15
+    }
16
+}

+ 0
- 19
backend/src/plugins/profile/handlers.js Datei anzeigen

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

+ 0
- 44
backend/src/plugins/profile/index.js Datei anzeigen

@@ -1,44 +0,0 @@
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 }

+ 0
- 22
backend/src/plugins/profile/responses.js Datei anzeigen

@@ -1,22 +0,0 @@
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 }

+ 0
- 15
backend/src/plugins/profile/validators.js Datei anzeigen

@@ -1,15 +0,0 @@
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 }

+ 12
- 8
backend/src/plugins/test.js Datei anzeigen

@@ -1,15 +1,19 @@
1
-import { handlers } from '../handlers/index.js'
2
-
3
-const testPlugin = {
4
-    name: 'test-plugin',
1
+module.exports = {
2
+    name: 'myPlugin',
5 3
     version: '1.0.0',
6 4
     register: async (server, options) => {
5
+        // Create a route for example
7 6
         server.route({
8 7
             method: 'GET',
9 8
             path: '/test',
10
-            handler: handlers.default.get
9
+            handler: async function (request, h) {
10
+                return { test: 'hello, world' }
11
+            },
12
+            options: {
13
+                description: 'Test',
14
+                notes: 'This is a test route',
15
+                tags: ['api'],
16
+            }
11 17
         })
12 18
     }
13
-}
14
-
15
-export { testPlugin }
19
+}

+ 90
- 0
backend/src/plugins/user.js Datei anzeigen

@@ -0,0 +1,90 @@
1
+const Schwifty = require('@hapipal/schwifty');
2
+const Joi = require('joi');
3
+
4
+const pluginConfig = {
5
+    name: 'my-user-plugin',
6
+    version: '1.0.0',
7
+    tableName: 'users',
8
+    handlerType: 'user',
9
+    docs: {
10
+        get: {
11
+            description: 'Get user',
12
+            notes: 'Returns a user item by the id passed in the path'
13
+        }
14
+    }
15
+}
16
+
17
+class User extends Schwifty.Model {
18
+    static get tableName() { return pluginConfig.tableName }
19
+    static get joiSchema() {
20
+        return Joi.object({
21
+            id: Joi.number().required(),
22
+            name: Joi.string().required()
23
+        })
24
+    }
25
+}
26
+
27
+const handlers = {
28
+    get: async request => {
29
+        try {
30
+            /** Get the data for your endpoint */
31
+            const { User } = request.models()
32
+            const all = await User.query()
33
+
34
+            return { 
35
+                ok: true,
36
+                handler: pluginConfig.handlerType,
37
+                data: { name: request.params.name, all },
38
+            }
39
+        }
40
+        catch(err) {
41
+            return { 
42
+                ok: false,
43
+                handler: pluginConfig.handlerType,
44
+                data: { error: err },
45
+            }
46
+        }
47
+    }
48
+}
49
+
50
+/** Validator functions by request method */
51
+const validators = {
52
+    get: {
53
+        params: Joi.object({
54
+            name: Joi.string().min(3).max(11),
55
+            all: Joi.array()
56
+        })
57
+    }
58
+}
59
+
60
+/** Plugin options by request method */
61
+const options = {
62
+    get: {
63
+        ...pluginConfig.docs.get,
64
+        tags: ['api'],
65
+        validate: validators.get,
66
+        response: {
67
+            schema: Joi.object({
68
+                ok: Joi.bool(),
69
+                handler: Joi.string(),
70
+                data: validators.get.params
71
+            }),
72
+            failAction: 'log'
73
+        }
74
+    }
75
+}
76
+
77
+module.exports = {
78
+    name: pluginConfig.name,
79
+    version: pluginConfig.version,
80
+    register: async server => {
81
+        await server.register(Schwifty)  
82
+        await server.registerModel(User)
83
+        await server.route({
84
+            method: 'get',
85
+            path: '/users/{name}',
86
+            handler: handlers.get,
87
+            options: options.get
88
+        })
89
+    }
90
+}

+ 0
- 11
backend/src/routes/index.js Datei anzeigen

@@ -1,11 +0,0 @@
1
-import { handlers } from '../handlers/index.js'
2
-
3
-const routes = [
4
-    {
5
-        method: 'GET',
6
-        path: '/',
7
-        handler: handlers.default.get
8
-    },
9
-]
10
-
11
-export { routes }

Laden…
Abbrechen
Speichern