Skip to content

Taffy Plus (v5.0.0) Deep Dive #460

Description

@dawesi

Like all concepts in Issue 459, and especially pushing taffy data down through the levels.

Went full dive on thinking this through and implmented a whole 'providers' config for this also and went crazy pretty much rewriting most of the framework into what i now call taffy 5.0.0 but it probably should be called taffy-plus now as it's a fork really, as it' kind of no longer just taffy, but was POC for all the things i 'need' to have in my api with 'simple' configs and customisable provdiders (roll your own) - oh and rest AND graph api implementations... (yeah i got excited)

you can configure providers for authn. formats (serialize/deserialize) [csv,json,xml,yaml,taffy,openapi,soap,rss], loggers, and opesec (fingerprint/waf[ip control/throttle) and planned to consume (and cache static resources) - also can have providers like status page to generate staus issues. Also working on event based hooks that can thow to an event bus, and a webhook logging provider to emit events ;-)

seems i'm basically starting to build the cf api manager all over again as a taffy-api-manager (lol)

Formatters can do serialization, formatting and generation all in one component per format.

it also detects environment based on ip/uris (and added hostname pattern also now)

of course EVERYTHING is configurable (or not) - so you can roll your own providers, or use none of them (there are some defaults like json serializers and a "none' authn) that wire basic wriring and keep out of your way) - so you can put zero configuration in and it just works. (and when no resources it generates a ping status endpoint ;-)

also wired in testbox and ui/js testing framework specs (for dash)

I basically went full wishlist on it so that i could work out the best way to configure it. Also came up with a way to have a global config so that I could roll this into a lucee extension and manage muliple versions of taffy at the same time (by using application mappings like this.mappings['/taffy'] = expandPath('/taffy5') (but now starting to implmenent a dynamic configuration in framework) and having the extension download the latest versions automatically at server level (in separate dirs) and then move the mapping to the latest version after validation.

Yeah i went so deep dive that i came out the other end.... so many ideas... and at simple level so easy to implement, but maybe we just need a taffyMetadata that is in the main object 'pile' also that can then also be generated out into docs.

Oh also built from scratch a whole new admin panel/playground based on tailwind css, playground is work in progress, but doc is fully functional and populates auth, request/response code in multiple langs (curl/lucee/php/etc) and pulls docs for open api from include::"" markdown docs to be included in openapi and dashboard generation.

It works, and is POC, but want to polish then will publish as a 'reference' point to github for you to enjoy. Until then keep going here... what i'm looking at is a backward compat version 5.0 really anyway... so many changes, updates and more.

It is wired 'production-ready' by default with zero config (reload and debug passwords and keys auto generated)

OR the whole config to be :

// optional config

variables.taffy = {
        "baseUri": "/",
        "taffy": {
            "version": "5.0.0"
        },
        "meta": {
            "title": "My Amazing APi",
            "version": "1.0.222",
            "changelog": "include::/docs/changelog/*.md",
            "catalog": {
                "category": "weather",
                "subcategory": "none",
                "tags": "weather"
            },
            "authors": [
                { "name": "Your Name", "email": "your.email@example.com" }
            ],
            "licence": { "name": "", "url": "" },
            "contacts": {
                "home": { 
                    "uri": "https://teamcfml.dev/"
                },
                "issues": { 
                    "uri": "https://teamcfml.dev/" 
                }
            }
        },
        "docs": {
            "all": {},
            "playground": {},
            "openapi": {}
        },
        "environments": {
            "dev": {
                "uris": ["taffy.devv"],
                "ips": ["127.0.0.1"]
            },
            "staging": {
                "uris": ["new-api.datataxi.au"]
            },
            "prod": {
                "uris": ["api.datataxi.au"]
            }
        },
        "features": {
            "cors": { "cossdomain": true },
            "cache": { "status": false },
            "reload": { "status": true, "key": "{reloadkey}", "password": "{reloadpassword}" },
            "resources": { "external": true, "fonts": "google" },
            "debug": { "status": true, "key": "{debugkey}" }
        },
        "headers": {
            "request": {},
            "response": {
                "X-Generated-By": "Taffy"
            }
        },
        "providers": {
            "authns": [
                "all": true
            ],
            "docs": [
                { "code": "openapi", "active": true, "resource": "/_openapi", "taffy_authn": "apikey" }, 
                { 
                    "code": "playground", 
                    "active": true, 
                    "resource": "/_playground", 
                    "play": true, 
                    "taffy_authn": "apikey", 
                    "headers": {}, 
                    "theme": "dark" 
                },
                { 
                    "code": "statuspage",
                    "active": true,
                    "path": "/_status"
                },
                { 
                    "code": "dashboard",
                    "active": true,
                    "path": "/_live"
                }
            ],
            "logs": [
                { "exception": { "file": { "context": true, "core": true } } },
                { "request": { "file": { "context": true, "core": true } } },
                { "events": { "file": true } }
            ],
            "formats": [
                "all": true
            ]
        }
    };
```

I know this is a little OT, but I managed to get this running also, and a stepping stone version passing taffy meta from a global json config (server-wide) to overlay the core config, then overlayed with app config.

So been a busy couple of days, and mostly handcoded, with some 'suggestions' from devin (ex winsurf) and Claude optus 4.8 discussing features, and SWE/Kimi for boilerplate updates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions