How to generate API s in YodaOS

On node JS community, in fact, there are many frameworks for generating restful APIs through Markdown, agreeing on the data required by the API according to a certain format, and then extracting these key data through parsing Markdown documents, and finally generating database models and HTTPS services.

YodaOS, as a front-end operating system, also uses similar technologies. The applications in YodaOS are divided into lightapp and extapp. The former is a light application integrated in the VUI daemon process. It is mainly used in a scene with simple interaction and rapid response, such as volume control, system control, etc. The latter, as an independent process, communicates with the main process through the Child Process. The use scenarios are mainly music, games, telephones and other applications that need to be used for a long time.

Why light applications? Light applications are more like a script. Whenever a user interacts once at a time, it only needs to call the functions defined in the corresponding script from the preloaded script to complete a response. Often, such application interactions are relatively simple. For this reason, it is necessary to create one interaction in the process of each interaction
ipc or even fork is a waste of performance and memory.

At the beginning of the design, we expect that for developers, there is no need to target different types of applications, just in the package JSON, and the YodaOS API should be completely consistent. In this case, we are faced with a problem. Even if we can achieve a high degree of abstraction, we need to modify two codes each time we add an interface. This is actually contrary to our original design intention.

 

API Descriptor

To this end, we introduced the concept of API Descriptor: https://github.com/yodaos-pro... . It can be regarded as a DSL written in JavaScript. It is used to describe each YodaOS API, including the definitions of namespace, event, method, etc. During initialization, the system will load all API descriptors, and then generate corresponding APIs in lightapp and extapp respectively.

Object.assign(ActivityDescriptor.prototype,
{

/**
 * When the app is active.
 * @event yodaRT.activity.Activity#active
 */
active: {
  type: 'event'
},
/**
 * When the Activity API is ready.
 * @event yodaRT.activity.Activity#ready
 */
ready: {
  type: 'event'
},
/**
 * When an activity is created.
 * @event yodaRT.activity.Activity#create
 */
created: {
  type: 'event'
}
}
)

 

The above code defines several events in the Activity: active, ready, and create. Therefore, it can be written as follows in any application:

module.exports = activity => {
activity.on('active', () => console.log('app activated'))
activity.on('ready', () => console.log('app is ready'))
activity.on('created', () => console.log('app is created'))
}

 

Next, let's see how "method" is defined:

Object.assign(ActivityDescriptor.prototype,
{

/**
 * Get all properties, it contains the following fields:
 * - `deviceId` the device id.
 * - `deviceTypeId` the device type id.
 * - `key` the cloud key.
 * - `secret` the cloud secret.
 * - `masterId` the userId or masterId.
 *
 * @memberof yodaRT.activity.Activity
 * @instance
 * @function get
 * @returns {Promise<object>}
 * @example
 * module.exports = function (activity) {
 *   activity.on('ready', () => {
 *     activity.get().then((props) => console.log(props))
 *   })
 * }
 */
get: {
  type: 'method',
  returns: 'promise',
  fn: function get () {
    return Promise.resolve(this._runtime.getCopyOfCredential())
  }
},
}
)

 

As you can see, just like defining events, you need to add the corresponding object in the prototype chain of the Descriptor, set the type to method, and then implement the function in fn.

module.exports = activity => {
activity.get().then(

(data) => console.log('credentialse is', data),
(err) => console.error('something went wrong', err))
}

In this way, in addition to unifying API definitions, it is also easier to generate unified API references to developers based on JSDoc, making the modification of the entire API easy to read, low threshold and low modification cost.

Guangzhou brand design companyhttps://www.houdianzi.com PPT template downloadhttps://redbox.wode007.com

API Translator

In YodaOS, how can the above Descriptor be generated into an interface directly used by developers? Now let's introduce the Translator we introduced.

translator s correspond to the application types we support. Therefore, for lightapp and extapp, we also have two translators:

In process https://github.com/yodaos-pro...
Interprocess https://github.com/yodaos-pro...

This article does not specifically expand the working principle of each translator, but will do some simple process introduction. Take translator IPC as an example:

module.exports.translate = translate
function translate (descriptor) {
if (typeof process.send !== 'function') {

throw new Error('IpcTranslator must work in child process.')
}
var activity = PropertyDescriptions.namespace(null, descriptor, null, null)
listenIpc()
return activity
}

Each translator provides a function, namely, translate(descriptor). It accepts a descriptor object, then traverses the objects in the prototype chain, generates an object called activity according to namespace, event and method, and finally returns this object to the developer.

When a developer uses an API, the activity object will be called to the VUI daemon according to the logic generated (agreed) in advance by the translator, and finally the result of the call will be returned through Promise to complete an interface call.

 

Tags: Framework

Posted by j4ymf on Fri, 03 Jun 2022 16:29:47 +0530