src/happyx

HappyX

Web framework written in Nim with ❤

Why HappyX? 🤔

HappyX is macro-oriented full-stack web framework that provides same syntax in both parts of framework (SPA and SSR).

  • SPA part compiles only on JS and provides these features:
    • components;
    • event handlers;
    • buildJs macro;
    • state management
  • SSR part compiles only on C/Cpp/Obj-C and provides these features:
    • CORS registration;
    • Request models;

SPA and SSR also provides both syntax for routing. You don't need to learn new syntax for new projects.

HappyX provides CLI tool for creating and serving your projects 🛠

Create new project ✨

hpx create

Serve existing SPA project 🛠

hpx dev

Help ❔

hpx help [subcommand]

Examples

SPA 🎴

SPA works only on JS backend

  • index.html
    <html>
      <head>
        <meta charset="utf-8">
        <title>Title</title>
      </head>
      <body>
        <div id="app"></div>
        <script src="main.js"></script>
      </body>
    </html>
  • components/hello_world.nim
    import happyx
    
    component HelloWorld:
      `template`:
        # Use HTML here
        tDiv:
          "Hello, world!"
      `script`:
        # Use real Nim code here
        discard
      `style`: """
        /* Use pure CSS here */
        div {
          color: green;
        }
        """
  • main.nim
    import
      happyx,
      components/[hello_world]
    
    appRoutes "app":
      "/":
        component HelloWorld

SSR 💻

SSR works only on C/Cpp/ObjC backends

  • main.nim
    import happyx
    
    serve "127.0.0.1", 5000:
      # In this scope you can declare gc-safe vars/lets
      var myVar = 0
      
      get "/":
        # available only on GET method
        # In this scope you can access to
        # req: Request  - current request
        # query: StringTableRef  - current queries
        # path: string  - current path
        myVar += 1
        return "Hello, world! myVar is {myVar}"
      
      "/framework":
        return "This method available from any method (POST, GET, PUT, etc.)"
      
      middleware:
        echo "This will printed first"
      
      notfound:
        return "Oops, not found!"

CLI Usage 🎈

SSR

At first we need to create project and choose SSR project type.

hpx create

This creates directory with .gitignore, README.md and main.nim files

After creating you can work with project as you want

SPA

At first we need to create project and choose SPA project type.

hpx create

This creates directory with .gitignore, README.md, main.nim and components/hello_world.nim files

After creating you can work with project as you want

cd PROJECT_NAME
hpx dev

hpx dev command will see all changes in your project and recompile main.nim

hpx build command will builds your project as standalone web application (HTML + JS files)

Path Params 🛠

Routing provides powerful path params.

Example

"/user{id:int}":
  # In this scope you can use `id` as assigned immutable variable
  ...
"/user{username}":
  # In this scope you can use `username` as assigned immutable variable
  ...

Validation ⚙

In path params you can describe every param if you need. Here is syntax overview.

  • Required param: {arg:type}, $arg:type, {arg}, $arg
  • Optional param: {arg?:type}, $arg?:type, {arg?}, $arg?
  • Mutable param: {arg:type[m]}, $arg:type[m], {arg[m]}, $arg[m]
  • Mutable optional param: {arg?:type[m]}, $arg?:type[m], {arg?[m]}, $arg?[m]
  • Optional param with default value: {arg:type=val}, $arg:type=val, {arg=val}, $arg=val
  • Mutable optional param with default value: {arg?:type[m]=val}, $arg?:type[m]=val, {arg?[m]=val}, $arg?[m]=val

Aliases 🎈

Path params can be used by default in curly brackets: {arg} But you can use syntax sugar (alias) also: $arg

Typing 👮‍♀️

Every path param keeps type (default is string)

List of types:

  • bool: can be on, 1, yes, true, y for true and off, 0, n, no and false for false
  • string: string that excludes / chars
  • enum(EnumTypeName): matches enum value
  • word: like string but excludes any symbols
  • int: any integer
  • float: any float
  • path: like string but includes / chars.
  • regex pattern: any regex pattern translates in string. Usage: /:patternHere:/. Doesn't provides optional and default.

(Im)mutable ⚙

Every path param by default is immutable, but you can change it to mutable by add [m] after param type:

ImmutableMutableImmutable Via AliasMutable Via Alias
{arg}{arg[m]}$arg$arg[m]
{arg:type}{arg:type[m]}$arg:type$arg:type[m]
{arg:type=default}{arg:type[m]=default}$arg:type=default$arg:type[m]=default
{arg=default}{arg=default}$arg=default$arg[m]=default
{arg?:type}{arg?:type[m]}$arg?:type$arg?:type[m]

Mounting 🔌

HappyX routing provides mounting also.

Here is example of mount declaration ✨

mount Settings:
  "/":
    ...
mount Profile:
  mount "/settings" -> Settings
  mount "/config" -> Settings

Here is example of mount usage 🎈

serve(...):  # or appRoutes 🍍
  # /profile does not works
  # /profile/settings does not works
  # /profile/settings/ works!
  mount "/profile" -> Profile

API Reference 📄

Automatic Import 🎈

Core 🔋

  • constants - describes all HappyX flags and consts.
  • queries - provides some utils to work with query parameters.
  • exceptions - describes all HappyX exceptions.
  • secure - provides some secure features.

Single Page Application ✨

Server Side Rendering 🍍

  • cors provides CORS registration.
  • server provides routing and working with server.
  • form data provides routing and working with server.
  • request models provides routing and working with server.
  • session provides working with sessions.
  • open api provides OpenAPI for HappyX.
  • utils provides some utils to work with HTTPHeaders, JSON and etc.

Template Engine 🎴

  • engine provides templates for SSR.

Routing 🔌

  • routing provides powerful routing and pathParams macro.
  • mounting provides powerful mounting.
  • decorators provides powerful decorators.

Syntax Sugar ✨

  • use provides use macro.
  • style provides buildStyle macro.
  • sgr provides -> macro.
  • js provides buildJs macro.

Language Binds ✌

Python 🐍

Exports

routes, []=, ModelBase, ., answerHtml, answerFile, fgColored, CustomHeaders, ApiDocObject, start, serve, initServer, liveview, answer, newServer, newCustomHeaders, Server, answerJson, newApiDocObject, modelFieldsGenerics, modelFields, model, parseFormData, parseXmlBody, parseXWwwFormUrlencoded, FormDataItem, addCORSHeaders, CORSObj, regCORS, startSession, Session, closeSession, startSession, closeSession, genSessionId, getSession, generate_password, check_password, HpxModelSyntaxDefect, throwDefect, HpxServeRouteDefect, HpxBuildStyleDefect, HpxPathParamDefect, HpxUseDefect, HpxMountDefect, HpxSyntaxSugarDefect, HpxBuildJsDefect, HpxCorsDefect, HpxBuildHtmlDefect, HpxTranslatableDefect, HpxAppRouteDefect, HpxComponentDefect, appName, enableUseCompDebugMacro, httpMethods, componentDebugTarget, enableDebug, sessionIdLength, htmlTagsList, enableHttpx, apiDocsPath, cryptoMethod, enableMicro, exportPython, enableDefaultDecorators, enableRoutingDebugMacro, HpxMajor, numThreads, enableSafeRequests, HpxVersion, HpxMinor, enableDebugTreeComponentMacro, reqModelDebugTarget, enableLiveViews, enableHttpBeast, exportJvm, HpxPatch, enableAutoTranslate, enableRequestModelDebugMacro, enableApiDoc, enableDebugSpaMacro, enableHistoryApi, enableDebugComponentMacro, nim_1_6_14, enableDebugSsrMacro, nim_2_0_0, use, parseQueryArrays, ?, parseQuery, NimKeywords, registerApp, buildHtml, routes, html, components, addArg, registerComponent, route, js, renderVdom, createdComponentsList, appRoutes, html, eventHandlers, BaseComponent, injectJs, lvl, initTag, currentComponent, currentComponentsList, ComponentEventHandler, tag, componentsResult, componentEventHandlers, elem, addArgIter, requestResult, UnclosedTags, textTag, initTag, [], buildComponentHtml, route, get, currentRoute, initTag, $, AppEventHandler, [], []=, tagFromString, tag, BaseComponentObj, findByTag, reRender, render, TagRef, toSeqIter, buildHtmlSlot, App, start, initTag, getAttribute, buildHtml, add, application, /, []=, %, /, <, toFloat, @=, toInt64, >=, ==, ~=, /=, ^, set, toInt16, /, $, @, <, +=, State, -, >, *=, @=, !, toInt8, ^=, -=, *=, %=, !=, /=, &, remember, :=, $=, <=, languageSettings, %=, ==, !, []=, :=, *, &, get, @, *, -=, %=, /=, |=, toInt, val=, not, &=, enableRouting, toCString, ^, +, $=, toSeq, %, <=, !, toBool, [], +=, !=, toString, @, >=, set, -=, &=, %, toChar, +, +=, &=, pairs, toFloat32, []=, |=, ~=, -, []=, <, items, ^, >, toFloat64, >, *=, &, :=, ->, len, ^=, |=, +, @=, toInt32, ~=, [], -, $=, *, ^=, [], [], regDecorator, decorators, decorator, DecoratorImpl, compDefArg, component, reRenderTmpl, importComponent, LanguageSettings, translate, translatable, nnkNumbers, buildStyle, render, renderTemplate, templateFolder, initTag, tag, textTag, addArgIter, initTag, TagRef, tag, toSeqIter, findByTag, []=, $, add, initTag, get, getAttribute, lvl, UnclosedTags, NimKeywords, initTag, tagFromString, [], addArg, [], getRouteParams, RouteObject, RequestModelObj, handleRoute, parseIntOrJString, convertJson, newRequestModelObj, PathParamObj, pathParams, parseFloatOrJString, parseBoolOrJString, exportRouteArgs, RouteDataObj, registerRouteParamType, newPathParamObj, mount, findAndReplaceMount, registeredMounts, sugarRoutes, ->, has, has, :=, buildJs, toHttpHeaders, toJsonNode