Skip to content

Instantly share code, notes, and snippets.

@kborchers
Created November 27, 2012 04:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kborchers/4152306 to your computer and use it in GitHub Desktop.
Save kborchers/4152306 to your computer and use it in GitHub Desktop.

#AeroGear.AutoConfig

The idea of this utility is to provide a method to automatically configure the client side connections to server resources (Pipeline) via a request for the JSON config to the server from an AeroGear client.

Currently, to set up and use a single connection to the server (pipe) you can use the following:

// Set up a pipeline which contains one pipe using the default REST adapter
var userPipeline = AeroGear.Pipeline( "users" ),
	users = userPipeline.pipes.users;

This is obviously a simplified example so the benefit is not as great but what if you could avoid all of the setup and just do:

var users = AeroGear.Config.users;

Maybe a more complex example would illustrate better:

// Set up a pipeline which contains two pipes using custom settings
var carPipeline = AeroGear.Pipeline({
		name: "oldCars",
		settings: {
			baseURL: "/resources/automobiles/",
			endpoint: "antique",
			recordId: "vin"
		}
	},
	{
		name: "newCars",
		settings: {
			baseURL: "/resources/automobiles/",
			endpoint: "concept",
			recordId: "customId"
		}
	}),
	oldCars = carPipeline.pipes.oldCars,
	newCars = carPipeline.pipes.newCars;

Again, wouldn't it be nice to just be able to go straight to accessing the pipes:

var oldCars = AeroGear.Config.oldCars,
	newCars = AeroGear.Config.newCars;

As you can see, the automatically configured pipes would be namespaced under the AeroGear.Config (name not set in stone) namespace to provide for protection against naming collisions.

In order to do this, what I am proposing is a method to generate a JSON formatted object server-side that the AeroGear client libraries can read and cache which would provide the necessary information to allow the client lib to automatically set up the necessary resources and make them available for use. Below I will describe some of my initial thoughts on how to make this happen which I hope will encourage some good discussion.


##AeroGear.AutoConfig.js This utility will be kept separate from the main aerogear.js distribution. By doing this, it allows for the act of including the file in the app to be the initiator that "turns on" the functionality.

By default, AeroGear.AutoConfig assumes the config can be found at a REST endpoint named config in the current context of the app. For example, if the app is running at mydomain.com/myapp, AeroGear.AutoConfig will make a request on the initial load of the app to mydomain.com/myapp/config. This endpoint can be customized by setting AeroGear.AutoConfigEndpoint to the custom endpoint after aerogear.js is loaded but before aerogear.autoconfig.js is loaded like this:

<script src="aerogear.js"></script>
<script>AeroGear.AutoConfigEndpoint = "/customConfig";</script>
<script src="aerogear.autoconfig.js"></script>

Discussion - Method for mapping app var names to pipe names generated by the config. This would allow for the use of pipes on the client side while knowing very little about how they are configured. This could be implemented in a subsequent release if at all.

##AeroGear.AutoConfig (iOS) TODO

##AeroGear.AutoConfig (Android) TODO


##Config Object

The config could contain a number of items to inform the client of what the server expects.

  • ###Base URL This is the base URL that should be used with all endpoints. If this is not specified, the client should assume that each endpoint configures its own path.

  • ###Endpoints Contains an array of key/value pairs of endpoint information.

    • ####Endpoint An endpoint contains a set of information describing the endpoint to the client so that it can configure itself for the developer. The actual endpoint property can use relative URLs to use the same context as the app, root relative URLs to assume the same domain but override the remainder of the path and then full URLs use that as the path to the endpoint. If a baseURL was specified though, the endpoint is appended to that baseURL in all cases.

Example Config

{
	baseURL: "/resources/automobiles/",
	endpoints: [
		{
		name: "oldCars",
		endpoint: "antique",
		recordId: "vin"
		},
		{
		name: "newCars",
		endpoint: "concept",
		recordId: "customId"
		}
	]
}
@matzew
Copy link

matzew commented Nov 27, 2012

So the equivalent to this:

// Set up a pipeline which contains two pipes using custom settings
var carPipeline = AeroGear.Pipeline({
        name: "oldCars",
        settings: {
            baseURL: "/resources/automobiles/",
            endpoint: "antique",
            recordId: "vin"
        }
    },
    {
        name: "newCars",
        settings: {
            baseURL: "/resources/automobiles/",
            endpoint: "concept",
            recordId: "customId"
        }
    });

Would be this, right?

var newCars = AeroGear.Config.newCars;
var oldCars = AeroGear.Config.oldCars;

Assuming the above works, then what about the following, would it work?

var newCars = AeroGear.Config.newCars;
var oldCars = myCarePipelineWhereIdontKnowHowIdefinedIt.pipes.oldCars;

Can I receive the "automatic" pipes ONLY from the "Config" namespace? So, could I receive the oldCars pipe like above?

@matzew
Copy link

matzew commented Nov 27, 2012

some questions/comments:

  • where does the MetaMagic in AeroGear.MetaMagic.newCars come from?
  • when adding autoconfig.js, explicit config is still possible? Or does "turn on", the autoconfig just works, IF one wants to use it
  • global config for all endpoints, hrm...

For iOS&Android the equivialent to var users = AeroGear.Config.users; needs a "baseURL", since (like on the pipes) they don't run w/in the "context"/"web-root". Once I have a better understanding of this, I will scratch something out for iOS...

@sebastienblanc
Copy link

About caching :

  • How will the config object be cached ? Using localStorage or in memory ?
  • How will the cache be evicted ?

About the server side :

  • Will the config be "hard coded" somewhere ? Or generated on the fly by parsing the "rest" annotation (this one will be nice) ?

General remarks :

  • As matzew mentioned, I think it will be nice if we could always access directly the pipe in the regular way :
    var oldCars = myCarePipelineWhereIdontKnowHowIdefinedIt.pipes.oldCars;

@kborchers
Copy link
Author

@matzew @sebastienblanc with regard to AeroGear.Config.newCars vs. myCarePipelineWhereIdontKnowHowIdefinedIt.pipes.oldCars, I like the idea of actually having access to the Pipeline. What if it was something like this instead:

AeroGear.AutoConfigPipeline.pipes.oldCars

@matzew AeroGear.MetaMagic.newCars was a typo from an earlier version. It should have been AeroGear.Config.newCars

@matzew You asked "explicit config is still possible?" Yes, you could still configure your own Pipeline(s) outside of the auto-configured one but once you include the file, you will get the auto-configured Pipeline.

@matzew "global config for all endpoints, hrm..." We can talk about that. It could be all endpoints, it could be only specific endpoints that the server wants opened up to all clients, or particular clients if we setup some API key or something to determine what client is requesting resources. This probably needs more input from others

@matzew The iOS/Android requirement for a baseURL is not a big deal, it could just always be included and JS could just use it too when using AutoConfig but still has the option to use app context when manually configuring

@sebastienblanc I was thinking caching would happen in localStorage or something a little more persistent than memory. We could generate an expiration when caching to know when we want to purge it and get a new config

@sebastienblanc I imagined the config being generated on the fly but that is a little beyond my skill set so someone else would need to chime in there. I think it would be much cooler if it was generated from the AeroGear back end. Of course, for it to work with any server side implementation, it could be hard coded and provided that way as well.

@matzew
Copy link

matzew commented Nov 27, 2012

AeroGear.AutoConfigPipeline.pipes.oldCars would be IMO a new pipe, or even an API... not sure, but initially I thought the auto-cfg builds the pipeline, so why not reusing that API ?

@matzew
Copy link

matzew commented Nov 27, 2012

@kbrochers "The iOS/Android requirement for a baseURL is not a big deal" - yes. just saying :-)

@kborchers
Copy link
Author

@matzew I wouldn't call it an API, I am just trying to namespace it to prevent name collisions and to make it globally available to your app. If it was just created the following way (pseudo code):

var cars = AeroGear.Pipeline({oldCarConfig, newCarConfig),
    oldCars = cars.pipes.oldCars;

You wouldn't have access outside of the AutoConfig IIFE and if it was, you could easily clobber that Pipeline by redefining the cars var. Make sense?

@lholmquist
Copy link

Will there ever be a point where someone does enough custom config that the "Magic" is no longer worth it? probably an edge case

@kborchers
Copy link
Author

@lholmquist Maybe, but like you said, probably an edge case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment