feat: added route for learningObjects
This commit is contained in:
		
							parent
							
								
									e8e1d94e5b
								
							
						
					
					
						commit
						d401136d3a
					
				
					 7 changed files with 116 additions and 10 deletions
				
			
		|  | @ -2,6 +2,8 @@ import express, { Express, Response } from 'express'; | ||||||
| import initORM from './orm.js'; | import initORM from './orm.js'; | ||||||
| import themeRoutes from './routes/themes.js'; | import themeRoutes from './routes/themes.js'; | ||||||
| import learningPathRoutes from './routes/learningPaths.js' | import learningPathRoutes from './routes/learningPaths.js' | ||||||
|  | import learningObjectRoutes from './routes/learningObjects.js' | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| const app: Express = express(); | const app: Express = express(); | ||||||
| const port: string | number = process.env.PORT || 3000; | const port: string | number = process.env.PORT || 3000; | ||||||
|  | @ -15,6 +17,7 @@ app.get('/', (_, res: Response) => { | ||||||
| 
 | 
 | ||||||
| app.use('/theme', themeRoutes); | app.use('/theme', themeRoutes); | ||||||
| app.use('/learningPath', learningPathRoutes); | app.use('/learningPath', learningPathRoutes); | ||||||
|  | app.use('/learningObject', learningObjectRoutes); | ||||||
| 
 | 
 | ||||||
| async function startServer() { | async function startServer() { | ||||||
|     await initORM(); |     await initORM(); | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								backend/src/config/config.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								backend/src/config/config.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | // Can be placed in dotenv but found it redundant
 | ||||||
|  | 
 | ||||||
|  | // import dotenv from "dotenv";
 | ||||||
|  | 
 | ||||||
|  | // Load .env file
 | ||||||
|  | // dotenv.config();
 | ||||||
|  | 
 | ||||||
|  | export const DWENGO_API_BASE = "https://dwengo.org/backend/api"; | ||||||
|  | 
 | ||||||
							
								
								
									
										20
									
								
								backend/src/controllers/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								backend/src/controllers/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | import { Request, Response } from "express"; | ||||||
|  | import { getLearningObjectsFromPath } from "../services/learningObjects.js"; | ||||||
|  | 
 | ||||||
|  | export async function getAllLearningObjects(req: Request, res: Response): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         const { hruid } = req.params; | ||||||
|  |         const language = req.query.language as string || "nl"; // Default to Dutch;
 | ||||||
|  | 
 | ||||||
|  |         if (!language) { | ||||||
|  |             res.status(400).json({ error: "Language query parameter is required." }); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const learningObjects = await getLearningObjectsFromPath(hruid, language); | ||||||
|  |         res.json(learningObjects); | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error("Error fetching learning objects:", error); | ||||||
|  |         res.status(500).json({ error: "Internal server error" }); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,16 +1,7 @@ | ||||||
| import { Request, Response } from "express"; | import { Request, Response } from "express"; | ||||||
| import axios from "axios"; | import axios from "axios"; | ||||||
| import { themes } from "../data/themes.js"; | import { themes } from "../data/themes.js"; | ||||||
| import dotenv from "dotenv"; | import { DWENGO_API_BASE } from "../config/config.js"; | ||||||
| 
 |  | ||||||
| // Load environment variables
 |  | ||||||
| dotenv.config(); |  | ||||||
| 
 |  | ||||||
| // Get API base URL from environment variables
 |  | ||||||
| const DWENGO_API_BASE = process.env.DWENGO_API_BASE as string; |  | ||||||
| if (!DWENGO_API_BASE) { |  | ||||||
|     throw new Error("DWENGO_API_BASE is not defined in the .env file"); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Fetch learning paths for a given list of HRUIDs. |  * Fetch learning paths for a given list of HRUIDs. | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								backend/src/routes/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								backend/src/routes/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | import express from "express"; | ||||||
|  | import { getAllLearningObjects } from "../controllers/learningObjects.js"; | ||||||
|  | 
 | ||||||
|  | const router = express.Router(); | ||||||
|  | 
 | ||||||
|  | // arg: hruid learningPath
 | ||||||
|  | // query: language
 | ||||||
|  | // Route to fetch list of learning objects based on hruid of learning path
 | ||||||
|  | router.get("/:hruid", getAllLearningObjects); | ||||||
|  | 
 | ||||||
|  | export default router; | ||||||
|  | @ -3,15 +3,20 @@ import { getLearningPathsFromIds, getLearningPathsByTheme, getAllLearningPaths, | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  | // query: language
 | ||||||
| // Route to fetch learning paths based on a list of HRUIDs
 | // Route to fetch learning paths based on a list of HRUIDs
 | ||||||
| router.get("/", getLearningPathsFromIds); | router.get("/", getLearningPathsFromIds); | ||||||
| 
 | 
 | ||||||
|  | // query: language
 | ||||||
| // Route to fetch all possible learning paths
 | // Route to fetch all possible learning paths
 | ||||||
| router.get("/all", getAllLearningPaths); | router.get("/all", getAllLearningPaths); | ||||||
| 
 | 
 | ||||||
|  | // query: language
 | ||||||
| // Route to fetch learning paths based on a searchterm
 | // Route to fetch learning paths based on a searchterm
 | ||||||
| router.get("/search", searchLearningPaths); | router.get("/search", searchLearningPaths); | ||||||
| 
 | 
 | ||||||
|  | // arg: theme id
 | ||||||
|  | // query: language
 | ||||||
| // Route to fetch learning paths based on a theme
 | // Route to fetch learning paths based on a theme
 | ||||||
| router.get("/theme/:theme", getLearningPathsByTheme); | router.get("/theme/:theme", getLearningPathsByTheme); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										67
									
								
								backend/src/services/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								backend/src/services/learningObjects.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,67 @@ | ||||||
|  | import axios from "axios"; | ||||||
|  | import { DWENGO_API_BASE } from "../config/config.js"; | ||||||
|  | 
 | ||||||
|  | interface LearningObjectNode { | ||||||
|  |     _id: string; | ||||||
|  |     learningobject_hruid: string; | ||||||
|  |     version: number; | ||||||
|  |     language: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export async function getLearningObjectsFromPath(hruid: string, language: string) { | ||||||
|  |     try { | ||||||
|  |         const learningPathUrl = `${DWENGO_API_BASE}/learningPath/${hruid}/${language}`; | ||||||
|  |         const learningPathResponse = await axios.get(learningPathUrl); | ||||||
|  |         const nodes = learningPathResponse.data.nodes; | ||||||
|  | 
 | ||||||
|  |         if (!nodes || nodes.length === 0) { | ||||||
|  |             throw new Error("No learning objects found in this learning path."); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return await Promise.all( | ||||||
|  |             nodes.map(async (node: LearningObjectNode) => { | ||||||
|  |                 const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`; | ||||||
|  |                 const metadataResponse = await axios.get(metadataUrl); | ||||||
|  | 
 | ||||||
|  |                 const html_url = `${DWENGO_API_BASE}/learningObject/getRaw?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`; | ||||||
|  | 
 | ||||||
|  |                 return filterLearningObjectMetadata(metadataResponse.data, html_url); | ||||||
|  |             }) | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error("Error fetching learning objects:", error); | ||||||
|  |         throw new Error("Failed to fetch learning objects."); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function filterLearningObjectMetadata(data: any, html_url: String) { | ||||||
|  |     return { | ||||||
|  |         key: data.hruid, | ||||||
|  |                 // hruid learningObject (not path)
 | ||||||
|  |         _id: data._id, | ||||||
|  |         uuid: data.uuid, | ||||||
|  |         version: data.version, | ||||||
|  | 
 | ||||||
|  |         title: data.title, | ||||||
|  |         html_url, | ||||||
|  |             // html content object
 | ||||||
|  |         language: data.language, | ||||||
|  |         difficulty: data.difficulty, | ||||||
|  |         estimated_time: data.estimated_time, | ||||||
|  |         available: data.available, | ||||||
|  |         teacher_exclusive: data.teacher_exclusive, | ||||||
|  |         educational_goals: data.educational_goals, | ||||||
|  |                 // list with learningObjects
 | ||||||
|  |         keywords: data.keywords, | ||||||
|  |                 // for search
 | ||||||
|  |         description: data.description, | ||||||
|  |                 // for search (not an actual description)
 | ||||||
|  |         target_ages: data.target_ages, | ||||||
|  | 
 | ||||||
|  |         // skos concepts needed ??
 | ||||||
|  |         // content type needed ??
 | ||||||
|  |         // content location ??
 | ||||||
|  |     }; | ||||||
|  | } | ||||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl