# HaxeShare (A simple, but powerful web framework)

**URL:** https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819
**Category:** Showcase
**Tags:** macro
**Created:** [June 18, 2019, 8:42pm UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819 "2019-06-18T20:42:45Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![tienery](https://community.haxe.org/user_avatar/community.haxe.org/tienery/32/964_2.png) [@tienery](https://community.haxe.org/u/tienery)
#### Post date: [June 18, 2019, 8:42pm UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819/1 "2019-06-18T20:42:45Z")

</div>

> [@nadako](#):
>
> I am curious why did you go with a custom format and then generate types from it with a macro, when you could just use a normal Haxe class or structure syntax and macro-generate the necessary support code directly from the type definition.

Okay, I’ve thought about the approach to use quite a lot for this project and have ultimately decided upon using more of a direct Haxe approach as you suggested, but not exactly in the way you describe.

I’ve called this new library [HaxeShare](https://github.com/persevere-and-motivate/HaxeShare) which I would suggest is far easier to use than previously.

Example:

```haxe
package;
#if macro

import hxshare.Builder;

class Generator
{

    public static function build()
    {
        Builder.init();

        Builder.beginStructure("PM_Department");
        Builder.addField("id", "ID");
        Builder.addField("shorttext", "URL");
        Builder.addField("shorttext", "Title", true);
        Builder.addField("longtext", "Description");

        Builder.build();
    }

}

#end

```

Of course, all the build and setup instructions are on the main page on GitHub.

**Original Post**

> [@tienery](#):
>
> Hello everyone!
> 
> I started building a macro-based web “expression” (or should I say, “scripting”) language which generates client- and server-side code. I made a YouTube video called “Building a Haxe Macro-powered Parser for the Web” on my Persevere and Motivate channel.
> 
> I have found perhaps a silly name for this, called “OWEL”. Since then, I have redeveloped it back into macro context with the potential for future customisable options.
> 
> The idea is quite simple. Take the following example:
> 
> ```haxe
> structure User
> @ID "ID" :hidden
> @TextField "User"
> @TextField "Password"
> 
> ```
> 
> Step-by-step, this code does the following:
> 
> 1. The first line is our `structure` definition. This is required for defining our types. Without it, the parser will not know the name to use to define our structures - it will also throw an error at compile-time.
> 2. On the second line and after contains our field definitions.
> 3. Field Types are prefixed with the `@` symbol. There are a few of them: `ID` , `TextField` , `TextArea` , `Date` , `Time` , `DateTime` , `Numeric` , `CheckBox` and `ComboBox` . At some point, there will be more options and eventually the ability to add your own.
> 4. After the Field Type, you must add in quotation marks the display value or name of the field. This is required by the parser. You may optionally add an option, like in the first field.
> 5. Options are prefixed with `:` using key-value notation. Keys cannot have spaces. Values can be a string or any series of characters without quotations. If you want to use reserved characters, always wrap your values in a string. You cannot mix them both. For example: `@TextField "Username" : id = "username"` .
> 6. In the above option example, this is unnecessary as the parser will generate the equivalent member name anyway. However, the `id` option is used in this instance to generate a different type value name if you wish. The Display Value in quotations may be passed through to runtime (in a later version) for display purposes.
> 7. Options can be on multiple lines, but the key-value pair must be on the same line. Eventually, when the macro API becomes available, you will be able to define how code is generated based on certain field options.
> 
> Also, this above code, which would be placed in a `*.owel` file, will be parsed into a `typedef TUser` under the `shared` package, available for both the client and server; and a `class` which is defined on the server.
> 
> I have taken out php-specific options with the goal to maximise compatibility across platforms. However, OWEL does take advantage of the `record-macros` library so server-side platforms will still be limited to their respective domains.
> 
> You can take a look at the project here: [GitHub - persevere-and-motivate/OWEL: Open Web Expression Language for Haxe web development.](https://github.com/persevere-and-motivate/OWEL)
> 
> For future reference, no platform-specific code will enter into this library, but I do intend to create RESTful notation, a platform-independent Router, and customisation options.

---

<div class="post-metadata">

### Author: ![nadako](https://community.haxe.org/user_avatar/community.haxe.org/nadako/32/5_2.png) [@nadako](https://community.haxe.org/u/nadako)
#### Post date: [June 18, 2019, 8:56pm UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819/2 "2019-06-18T20:56:30Z")

</div>

I am curious why did you go with a custom format and then generate types from it with a macro, when you could just use a normal Haxe class or structure syntax and macro-generate the necessary support code directly from the type definition.

---

<div class="post-metadata">

### Author: ![tienery](https://community.haxe.org/user_avatar/community.haxe.org/tienery/32/964_2.png) [@tienery](https://community.haxe.org/u/tienery)
#### Post date: [June 18, 2019, 9:04pm UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819/3 "2019-06-18T21:04:30Z")

</div>

Hmm… Well, I suppose I could, for example, implement `typedef` which Haxe at macro context could then generate the respective server class, but then there is also a number of metadata tags you might want to add to these variables to customise and define output.

However, there are customisation options I would like to add for language-specific targets.

Say, for example, you want to generate type references for WPF or WinForms on the C# target, or Swing on the Java target, or any other UI element for any other framework. The options are endless but having metadata stacked up on each other for these options is potentially messy. At least to me it looks messy.

With a custom format, it’s potentially easier to read to be able to define or even add extra Field Types for their relevant target-specific frameworks.

However, I suppose as this project grows we would have to wait and see if this is true in practice and how much of a benefit it might be to use metadata over a custom format.

EDIT: The custom format approach is for readability which I think is important for a project of this scale.

---

<div class="post-metadata">

### Author: ![tienery](https://community.haxe.org/user_avatar/community.haxe.org/tienery/32/964_2.png) [@tienery](https://community.haxe.org/u/tienery)
#### Post date: [July 8, 2019, 4:43pm UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819/4 "2019-07-08T16:43:03Z")

</div>

I have now added the following features to HaxeShare:

1. A server-based router generated into a RESTful API.
2. Added a hash-based client-side router class.

 ![imgur](https://community.haxe.org/uploads/default/original/1X/997237c12de839ab7abec8163bce3ff8458f2ea6.png)

Please see updated project and documented README on [GitHub](https://github.com/persevere-and-motivate/HaxeShare) for full details.

---

<div class="post-metadata">

### Author: ![tienery](https://community.haxe.org/user_avatar/community.haxe.org/tienery/32/964_2.png) [@tienery](https://community.haxe.org/u/tienery)
#### Post date: [February 12, 2020, 6:28am UTC](https://community.haxe.org/t/haxeshare-a-simple-but-powerful-web-framework/1819/5 "2020-02-12T06:28:14Z")

</div>

I have added a lot more beneficial features to this project since the last time it was updated. Here are the patch notes:

- Removed `searchable` from `Builder.addField`. Searching now requires an object from the client.
- Added ability to create custom REST components.
- The `id` parameter of the generated `modify` function of database objects is now of type `Dynamic` for greater flexibility.
- Added `isPrimary` parameter to `Builder.addField` to specify what field should be the primary key in the generated database object.
- Added `Router.remainder` function to retrieve the remaining route components as a string from the currently matched index.
- The `Request.get` function should call `cb` with `false` even if a status code of `200` is not given. This allows for greater flexibility on finding issues on the server-side.

In addition to these changes being found on [GitHub](https://github.com/persevere-and-motivate/HaxeShare), you can also find this project on [Haxelib](https://lib.haxe.org/p/haxeshare/) now.
