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 ??
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue