DEV Community

Cover image for JS Proxies
Kyle Parisi
Kyle Parisi

Posted on • Updated on

JS Proxies

You might be using proxies without knowing it

If you write an application in Vuejs or from what I can tell, React was using proxies before. Proxies are like giving your objects (only objects) super powers. Let me describe what you can do with an example.

Dyn

In a previous post, I talk about my take on dynamodb.

Every time I look at the Dynamodb SDK docs, I think 'man this is an over engineered hot mess'.

The API is not intuitive and requires googling every time. Every operation requires a js object to be sent to Dynamodb's API. It made me wonder if I could mask the js object with a js proxy. I think it provides for a cleaner and more memorable interface. The idea started with a single signature.

create[table] = {}

Could I create a dynamodb record with that as simple interface?

const create = new Proxy(
  {},
  {
    get: function(target, name) {
      return target[name];
    },
    set: function(obj, prop, value) {
      const params = {
        TableName: prop,
        Item: value
      };
      obj.promise = docClient.put(params).promise();
    }
  }
);

Hopefully you can see the above generates the parameters required for dynamodb's docClient (so I don't have to look them up). It also stores the promise in the object (create.promise) if you need to know when it's done creating the object.

It worked. So I made more operations into a library I called, Dyn:

GitHub logo kyleparisi / dyn

Experiment library to read from dynamodb

Dyn

Super crude idea for a library to talk with dynamodb. Does not handle paging at the moment. An interesting use of js proxies.

npm i @nargella/dyn
const Dyn = require("@nargella/dyn");
const AWS = require("aws-sdk");
AWS.config.region = "us-east-1";
const {
  reader,
  query,
  queryByIndex,
  queryAndFilter,
  scan,
  create,
  update,
  updateConditionally,
  del
} = new Dyn(new AWS.DynamoDB.DocumentClient());

See dyn_data for some data.

Create

// create[table] = {}
create.ProductCatalog = {
  Id: 500,
  Price: 222,
  ProductCategory: "Bicycle",
  Title: "99-Bike-212",
  BicycleType: "Hybrid",
  Brand: "Brand 212",
  Color: ["Red"],
  Description: "212 Description"
}

Read

Basic key/value:

// reader[table]({partitionkey: value, [sortkey: value]})
await reader.Movies({

Gotchas

Proxies are very cool but there are 2 things that caught me off guard. Firstly, the root object gives you nothing. In the above example I can't proxy the create key to anything. Secondly, you can't nest properties as a single proxy definition.

Proxy design

Discussion (0)