Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

MoodleNet: Difference between revisions

From MoodleDocs
No edit summary
No edit summary
Line 60: Line 60:


  }
  }
===== Your MN package must declare its dependency to the @moodlenet/core package. =====
===== Your MN package must declare its dependency to the @moodlenet/core package. =====
The core will import the main module at startup.
The core will import the main module at startup.
Line 88: Line 87:


  })
  })
===== Test the package template =====
===== Test the package template =====
* adding the template package in installation dependencies
* adding the template package in installation dependencies
* delete "installed” prop in the MoodleNet lock file
* delete "installed” prop in the MoodleNet lock file
* restart the backend
* restart the backend
Edit '''.dev-machines/my-dev/package.json''' adding the template package folder as dependency, similarly to other core package dependencies.
Edit '''.dev-machines/my-dev/package.json''' adding the template package folder as dependency, similarly to other core package dependencies.
  // .dev-machines/my-dev/package.json
  // .dev-machines/my-dev/package.json
Line 111: Line 107:


  }
  }
===== Define and deploy APIs =====
===== Define and deploy APIs =====
Your package will probably need to define and deploy its own APIs.
Your package will probably need to define and deploy its own APIs.
Line 146: Line 141:
  // my-moodlenet-package/1.0/hello/world
  // my-moodlenet-package/1.0/hello/world


===== Extend the web application =====
Use @moodlenet/react-app "plugin” api, during initialization to extend the web-app with a custom set of components.
import { pkgConnection } from '@moodlenet/core'
import reactApp from '@moodlenet/react-app'
const reactAppPkg = await pkgConnection(import.meta, reactApp)
await reactAppPkg.api('plugin')({
  mainComponentLoc:
     [‘path’, 'to', 'MainComponent.jsx']
})
The react-app will inject your MainComponent.jsx in the web-app codebase, recompile and bundle (webpack) and serve the new extended webapp.
===== APIs access =====
Apis can be accessed by any package in system running in backend’s NodeJs process using specific @moodlenet/core functions pointing to the path of the desired API.
// from within the backend:
// locate an package api by path
import myMNPkgConn from
   ‘my-moodlenet-package’
const myMNPkg = await pkgConnection(import.meta, myMNPkgConn)
const helloWorldApi =
  myMNPkg.api(‘hello/world’)
// call api as an async function
const result = await
  helloWorldApi(helloParam, worldParam)
APIs Primary Adapters
Primary adapters implement API accessibility from external processes using some transport and protocols.  Currently MoodleNet provides one Api-primary-adapter to access APIs by HTTP, which is implemented by @moodlenet/http-server.  @moodlenet/http-server API HTTP adapter exposes package APIs as HTTP-POST endpoints.  That endpoint is a path comprising the package name and the defined API path base, after the base API endpoint ( currently .pkgs ), having a JSON object body representing the api arguments. For example,<blockquote>
.pkgs/my-moodlenet-package/1.0/hello/world
body:
{
 "args” : [
   "hello-param1”,
   "world-param2”


 ]


}</blockquote>





Revision as of 14:33, 29 November 2022

Moodlenet-logo.png

What is MoodleNet?

MoodleNet is a flexible Open Education Technology platform for curating collections of the best known Open Educational (and other) Resources. You'll find more general information in the MoodleNet user documentation.

If you are looking to get started as a MoodleNet developer, we recommend taking the MoodleNet for Developers course with Moodle Academy.

Current status

Take a look at MoodleNet releases in our Tracker.

Roadmap

MoodleNet architecture

MoodleNet is a full stack TypeScript/JavaScript system using:

  • NodeJs
    • NPM Packages [1]
    • ESM Modules [2]
  • Browsers

MoodleNet development environment

Setup development environment

From the command line interface (CLI):

Ensure ArangoDB is running on localhost

docker run -e ARANGO_NO_AUTH=1 -p 8529:8529 --rm --name=mn3arango arangodb

Clone the repository

git clone https://gitlab.com/moodlenet/moodlenet.git

Initialize the project

cd moodlenet
yarn
yarn init-dev

Install a development deployment

yarn dev-install-be my-dev

Run development backend

yarn dev-backend my-dev

Questions? Please take a look in the MoodleNet Community and Tracker for answers or to ask for help.

Creating MoodleNet packages

A Moodlenet package is a standard ESM package defining a main ESM module.

@moodlenet/core will import it at startup.

// package.json
{
  "name”: "my-moodlenet-package”,
  "version”: "1",
  "type": "module",
  "exports": {
    ".": "./src/server/main.mjs"
  }
}
Your MN package must declare its dependency to the @moodlenet/core package.

The core will import the main module at startup.

The package "connects” to the core:

// package.json
{
   "peerDependencies”: {
     "@moodlenet/core”: "^0.1.0”
  }
}

When adding/removing peerDependencies in the main repository based development environment, remember to execute:

yarn bs

to link dependent packages.

// src/server/main.mjs
import { connectPkg } from '@moodlenet/core'
const connection = await connectPkg(import.meta, { 
  apis: { } 
})
Test the package template
  • adding the template package in installation dependencies
  • delete "installed” prop in the MoodleNet lock file
  • restart the backend

Edit .dev-machines/my-dev/package.json adding the template package folder as dependency, similarly to other core package dependencies.

// .dev-machines/my-dev/package.json
{
  ...
  "dependencies”:{
    ...
    "my-moodlenet-mjs-pkg-template”: "file:[repofolder]/packages/my-moodlenet-mjs-pkg-template”
  }
}
Define and deploy APIs

Your package will probably need to define and deploy its own APIs.

APIs are simply a collection of async functions - along with a params formal validation function - organized in a structured Js object.

APIs will be registered in the system with a path-like string, having your package name as prefix and apth following api structure.

// src/server/main.mjs
import { connectPkg, defApi } from '@moodlenet/core'
const myApis = {
  hello:{
     world: defApi( ctx => 
        async (p1,p2) => { return // something } , 
       (...params) => { /* … validate params */ }
  )
}
const connection = await connectPkg(import.meta, { 
  apis: myApis 
})
// will register 1 api: 
// my-moodlenet-package/1.0/hello/world
Extend the web application

Use @moodlenet/react-app "plugin” api, during initialization to extend the web-app with a custom set of components.

import { pkgConnection } from '@moodlenet/core'
import reactApp from '@moodlenet/react-app'
const reactAppPkg = await pkgConnection(import.meta, reactApp)
await reactAppPkg.api('plugin')({
  mainComponentLoc: 
     [‘path’, 'to', 'MainComponent.jsx']
})

The react-app will inject your MainComponent.jsx in the web-app codebase, recompile and bundle (webpack) and serve the new extended webapp.

APIs access

Apis can be accessed by any package in system running in backend’s NodeJs process using specific @moodlenet/core functions pointing to the path of the desired API.

// from within the backend:
// locate an package api by path
import myMNPkgConn from
   ‘my-moodlenet-package’
const myMNPkg = await pkgConnection(import.meta, myMNPkgConn)
const helloWorldApi =
  myMNPkg.api(‘hello/world’)
// call api as an async function
const result = await
  helloWorldApi(helloParam, worldParam)

APIs Primary Adapters

Primary adapters implement API accessibility from external processes using some transport and protocols. Currently MoodleNet provides one Api-primary-adapter to access APIs by HTTP, which is implemented by @moodlenet/http-server. @moodlenet/http-server API HTTP adapter exposes package APIs as HTTP-POST endpoints. That endpoint is a path comprising the package name and the defined API path base, after the base API endpoint ( currently .pkgs ), having a JSON object body representing the api arguments. For example,

.pkgs/my-moodlenet-package/1.0/hello/world

body:

{

 "args” : [

   "hello-param1”,

   "world-param2”

 ]

}



Important links