/dubbo-dj

A dsl tool that generates dubbojs code

Primary LanguageTypeScriptApache License 2.0Apache-2.0

dj

A dsl tool that generates dubbo code

Node.js CI

getting started

installation

npm i -g @dubbo/dj

command

> djc
Usage: dj [options]

A dsl tool that generate dubbo code ❤️

Options:
  -V, --version   output the version number
  -i, --init      init dubbo dsl project in current dir
  -b, --build     support generate language such as java, go, ts (default: "ts")
  -h, --help      display help for command

DSL API

e object


e

args type description required
name string e class name true
comment string e class comment false

field

args type description required
name string e field name true
type e, enum, dl.{Integer, String, Boolean, Char...} e field type true
comment string e field comment false

ok

it means that we finish the e declaration.


Talk is cheap, Show me the code!!

// dl means dubbo-lang ^_^
import { dl } from '@dubbo/dj'

const user = dl
  .e('org.apache.dubbo.e.User')
  .field('id', dl.Integer)
  .field('name', dl.String)
  .field('email', dl.String)
  .ok()

from djc compile, it will be emit source code like this,

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

import java from 'js-to-java'

export interface IUser {
  id: number
  name: string
  age: string
}

export default class User {
  id: number
  name: string
  age: string

  constructor(props: IUser) {
    this.id = props.id
    this.name = props.name
    this.age = props.age
  }

  __fields2java() {
    java('org.apache.dubbo.e.User', {
      id: java.Integer(this.id),
      name: java.String(this.name),
      age: java.String(this.age),
    })
  }
}

enum


enumer

args type description required
name string enum class name true
comment string enum class comment false

field

args type description required
name string enum field name true
type string, number enum field type true
comment string enum field comment false

ok

it means that we finish the e declaration.


Talk is cheap, Show me the code!!

const color = dl
  .enumer('org.apache.dubbo.e.Color')
  .field('Red', 0, '红色')
  .field('Green', 1, '绿色')
  .field('Blue', 2, '蓝色')
  .ok()

const fileType = dl
  .enumer('org.apache.dubbo.e.FileType')
  .field('PDF', 'PDF', 'PDF')
  .field('MP3', 'MP3', 'mp3')
  .ok()

from djc compile, it will be emit source code like this,

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

export enum Color {
  /**
   * 红色
   */
  Red = 0,

  /**
   * 绿色
   */
  Green = 1,

  /**
   * 蓝色
   */
  Blue = 2,
}

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

export enum FileType {
  /**
   * PDF
   */
  PDF = 'PDF',

  /**
   * mp3
   */
  MP3 = 'MP3',
}

s


s

args type description required
name string enum class name true
comment string enum class comment false

group

args type description required
name string group name false

version

args type description required
name string version number true

method

args type description required
name string method name true

arg

args type description required
name string method arg name true
type enum/e, dl.{String...} method arg type true

ret

args type description required
name any method return value false

ok

it means that we finish the s declaration.


Talk is cheap, Show me the code!!

import { dl } from '@dubbo/dj'
import { user } from './e'

export const userService = dl
  .s('org.apache.dubbo.s.UserService')
  .group('')
  .version('1.0.0')
  .method('sayHello')
  .arg('user', user)
  .ret(user)
  .method('sayWorld')
  .arg('name', dl.String)
  .ret(dl.String)
  .ok()

from djc compile, it will be emit source code like this,

=> UserService (Abstract LangService)

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

import User, { IUser } from '../../e/User'
import java from 'js-to-java'

export default abstract class UserService {
  dubboInterface = 'org.apache.dubbo.s.UserService'
  group = ''
  version = '1.0.0'
  methods = {
    sayHello: async (user: IUser) => {
      const res = await this.sayHello(user)
      return new User(res).__fields2java()
    },
    sayWorld: async (name: string) => {
      const res = await this.sayWorld(name)
      return java.String(res)
    },
  }

  abstract sayHello(user: IUser): Promise<IUser>

  abstract sayWorld(name: string): Promise<string>
}

=> UserServiceImpl (Dubbo provider s)

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

import { IUser } from '../e/User'
import UserService from './base/UserService'

export default class UserServiceImpl extends UserService {
  async sayHello(user: IUser): Promise<IUser> {
    throw new Error('Method not implemented.')
  }

  async sayWorld(name: string): Promise<string> {
    throw new Error('Method not implemented.')
  }
}

=> consumer (dubbo invoker)

/**
 * auto generated by dubbo dj
 * ~~~ 💗 machine coding 💗 ~~~
 */

import { Dubbo, TDubboCallResult } from 'apache-dubbo-js'
import { argumentMap } from 'interpret-util'
import { IUser } from '../../e/User'

export interface IUserService {
  sayHello(user: IUser): TDubboCallResult<IUser>

  sayWorld(name: string): TDubboCallResult<string>
}

export const UserServiceWrapper = {
  sayHello: argumentMap,
  sayWorld: argumentMap,
}

export function UserService(dubbo: Dubbo): IUserService {
  return dubbo.proxyService<IUserService>({
    dubboInterface: 'org.apache.dubbo.s.UserService',
    methods: UserServiceWrapper,
  })
}

the gen code structure, We will support java and go soon.

.
├── go
├── java
└── ts
    └── org
        └── apache
            └── dubbo
                ├── e
                │   └── User.ts
                └── s
                    ├── UserService.ts
                    ├── base
                    │   └── UserService.ts
                    └── consumer
                        └── UserService.ts

10 directories, 4 files

build api

import { djc } from '@dubbo/dj'
import * as e from './e'
import * as s from './s'

djc({
  buildEntry: { e, s },
  config: {
    lang: ['ts'], // optional(support multiple value), ts, go, java
    type: ['s'], // optional (support multiple value), e, consumer, s, serviceImpl
  },
})