Recent submissions

Comment · 6 months ago
As one of the original authors of Cargo, I agree. lockfiles are for apps and CLIs are apps. QED.
Comment · 4 years ago
Certainly!
Comment · 4 years ago
Comment · 4 years ago
Comment · 6 years ago
You're absolutely right. We took a lot of inspiration from the MobX API design.

One thing worth calling out: MobX requires you to mark getters as `@computed`:

  class OrderLine {
      @observable price = 0
      @observable amount = 1

      @computed get total() {
          return this.price * this.amount
      }
  }

The equivalent Octane class:

  class OrderLine {
    @tracked price = 0
    @tracked amount = 1

    get total() {
      return this.price * this.amount
    }
  }
This is more important than it looks. The fact that you don't need to decorate the getter also means that you can break up a computation that uses tracked properties into smaller functions without needing to think about how the smaller pieces should be written. You just use functions.

Here's what happens when you try to add methods with arguments to MobX:

  import { observable } from "mobx"
  import { computedFn } from "mobx-utils"

  class Todos {
    @observable todos = []

    getAllTodosByUser = computedFn(function getAllTodosByUser(userId) {
      return this.todos.filter(todo => todo.user === userId))
    })
  }
And Octane:

  import { tracked } from "@glimmer/tracking";

  class Todos {
    @tracked todos = [];

    getAllTodosByUser(userId) {
      return this.todos.filter(todo => todo.user === userId))
    }
  }
The rule in Octane is: "mark any reactive property as @tracked, and use normal JavaScript for derived properties". That's pretty cool!
Comment · 6 years ago
Comment · 6 years ago
I think that's probably a good change to the default. Today, `ember build` is analogous to `ember s`, and most people deploy to production with `ember-cli-deploy`.

But that's not a good enough reason :)

Thanks for surfacing this!

Comment · 6 years ago
You got that right.

We got a lot of inspiration from the React ecosystem, both in terms of component design (the root element is just another element) and composition.

Those changes played out differently in the context of Ember, because of the way our APIs work, but the core ideas are sound, and I'm happy that the React community paved the way.

Comment · 6 years ago
Comment · 7 years ago
Ultimately, the value prop of a tool like Graphiti or GraphQL is independent of the exact details of the wire format.

Graphiti uses JSON:API[1] under the hood as its protocol, which is a language-independent protocol with a wide variety of clients[2], and is now built-in to Drupal[3].

I designed JSON:API in ~ 2013 with a narrow purpose: to describe a protocol for incrementally communicating with server-side graphs over HTTP.

By incremental, I mean the possibility of fetching exactly the data you need at first, but then slowly filling in more data over time as a user interacts with an application.

URLs are a great "internet pointer", so when I was looking for a way to link fetched data with other not-yet-fetched data, URLs were the natural answer. On the other hand, a lot of REST APIs at the time didn't have a good way to eagerly send a whole bunch of graphy data down at once.

JSON:API's concept of linkage supports both models: a type/id pair for data the client already knows about and a URL for data it doesn't. You can even combine the two, to enable incremental refreshing of a piece of data that you fetched as part of the first request (simply by hitting the URL).

JSON:API was designed to work well with many kinds of client-side approaches, including ORMs. This meant using a composite key of type/id to identify records and not just a single ID. Over time, this has become a best practice for other tools in the space[4][5]

OData exists in a similar space as JSON:API, but JSON:API is much more tightly focused on the problem of incrementally fetching a graph of data from the server into the client. Focus is good :)

[1]: https://jsonapi.org/ [2]: https://jsonapi.org/implementations/ [3]: https://www.drupal.org/project/jsonapi [4]: https://graphql.org/learn/queries/ [5]: https://levelup.gitconnected.com/basics-of-caching-data-in-g...

Comment · 7 years ago
> It doesn't appear to solve some or the 2 major headaches graphQL is great at solving: * clients choosing how much data they need. On a desktop on broadband client, I want details of a list of entities, while on a mobile app with limited screen space and less bandwidth, I just need the skinny details like title and summary.

JSON:API solves this problem through sparse fieldsets[1]. Graphiti clarifies the spec by allowing sparse fieldsets at any level of nesting. As the original author and a current editor of the spec, I think we should adopt this extension into the spec proper.

> * pooling requests to multiple domains into a single request

JSON:API operates against a logical "graph in the sky", just like GraphQL. Graphiti makes it possible to mix and match database queries with other services and even plain Ruby objects[2].

One nice thing about this approach is that you still get to make database queries that take advantage of indexes and other database optimizations organically and by default. GraphQL's field-based approach can often result in a lot of extraneous database queries in the service of a homogenous server API that is based on fields.

(In my experience working with GraphQL APIs, I've seen a lot of performance issues that could only be debugged as "why is this field slow" that could have benefited a lot from making a big chunk of the query against a SQL database, directly using decades of optimizations around query planning).

[1]: https://jsonapi.org/format/#fetching-sparse-fieldsets [2]: https://www.graphiti.dev/cookbooks/without-activerecord

Comment · 8 years ago
I split my time between Ruby, JavaScript (mostly with TypeScript) and Rust, with occasional Java and devops work. Of those, JavaScript (with TypeScript) is my predominant language at the moment, but the mix changes pretty often.

Skylight's stack is Rust and Ruby for the agent, Rails for the backend, Java for our data processing pipeline (essentially a custom data store) and Ember for virtually the entire front end. The graphs in Skylight are Ember components written in d3.

I still think that Rails is a great choice for most web apps, since (to this day) it provides an extremely productive baseline for building account management and working with third-party integrations, which turn out to be a surprising percentage of the total code (and an even higher percentage of backend code changes) in even an ambitious project like Skylight.

I also think it's reasonable to use something like Java or Rust for any heavy data-crunching your app might do, but I think people over-estimate which aspects of their application are truly performance and efficiency critical.

Comment · 8 years ago
Comment · 8 years ago
For clarity, we also support almost all Rack-based frameworks in Ruby (including Sinatra):

https://www.skylight.io/support/advanced-setup

We should probably update our copy to clarify this point in the prominent places where it isn't already clear.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton