Giter VIP home page Giter VIP logo

falcor.net's Introduction

Falcor.NET Build status Gitter

What is Falcor?

Falcor is an approach pioneered by Netflix that enables you to quickly build a data-driven APIs that deliver efficient payloads to a variety of client form factors, and is able to adapt quickly to changing data access patterns as your application evolves.

Falcor provides many of the benefits of both REST and RPC, while addressing shortcomings these approaches face when building modern web applications.

Release Status: Developer Preview

Falcor.NET will remain in developer preview until a stable client and server reference version is released from Netflix all baseline functionality is implemented. Follow progress on this GitHub issue: #1

NuGet Packages NuGet package version Pre-release builds

Although Falcor.NET is still in pre-release, regular updates are posted to NuGet.org. More frequent pre-release builds can be found on MyGet.

Getting Started

To get started with Falcor.NET, follow these steps:

  1. In your ASP.NET web project, install the Falcor.Server.Owin NuGet package:
PM> Install-Package Falcor.Server.Owin -Pre
  1. Create your application router to match paths to a virtual JSON Graph model:
public class HelloWorldRouter : FalcorRouter
{
    public HelloWorldRouter()
    {
        // Route to match a JSON path, in this case the 'message' member
        // of the root JSON node of the virtual JSON Graph
        Get["message"] = async _ =>
        {
            var result = await Task.FromResult(Path("message").Atom("Hello World"));
            return Complete(result);
        };
        // Define additional routes for your virtual model here
    }
}

Note: For a more realistic example router, see the example Netflix router which is part of Falcor.Examples.Netflix.Web project that you can run yourself to see the router in action.

  1. In your OWIN startup class, configure your Falcor.NET router endpoint:
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseFalcor("/helloWorldModel.json", routerFactory: config => new HelloWorldRouter());
        ...
    }
}

If you are using IIS (and for most development environments), ensure the web.config has a similar handler configured for your model endpoint:

<system.webServer>
  <handlers>
    <add name="NetflixFalcorModelHandler" path="model.json" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>
  1. Using falcor.js in your client, create a new Falcor model, specifying the URL of your new endpoint for your datasource:
var model = new falcor.Model({
  source: new falcor.HttpDataSource('/helloWorldModel.json')
});
  1. You've done all you need to talk to your router, call your model like so:
model.get('message').then(function(json) {
  console.log(json);
});
// Result:
{
  json: {
    message: "Hello World!"
  }
}

When To Use Falcor

**_Consider the Falcor approach when you are developing a client/server architecture that is intended to provide a rich client user experience._**
Good Fit Poor Fit
Fetching large amounts of small resources (e.g. web components, JSON, metadata, etc.) Fetching small amounts of large resources (e.g. web pages, images, files, etc.)
Aggregating heterogeneous services efficiently (e.g. microservices or loosley-coupled modules) Speaking to a single back-end data source or service provider
Delivering responsive and capable end-user client experiences Systems integration and public APIs; static websites
Heterogeneous and evolving data access patterns (multiple devices, changing use cases)

License

Apache 2.0

falcor.net's People

Contributors

craigsmitham avatar darcy-buttrose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

falcor.net's Issues

Question about Ref

Hey,

I have been trying to follow the advanced examples for falcor. I am trying to recreate the "all" route but I am running into odd results. I am not sure if it is a bug with the falcor.net project or my client code. Here is what I have.
Any ideas what I am doing wrong?

In NetflixFalcorRouter

Get["titles[{ranges:indices}]"] = async parameters => {
    List<int> titleIds = parameters.indices;

    var ratings = await ratingService.GetRatingsAsync(titleIds.Select(x => Guid.NewGuid()), userId);
    var results = titleIds.Select(idx => {
        var rating = ratings.ElementAtOrDefault(idx);

        return Path("titles", idx)
            .Ref("titlesById", rating.TitleId.ToString());
    });

    return Complete(results);
};

Client index.html

model.get('titles[0..2]["rating", "userRating"]').then(logJson, logJsonError);

Output

{
   "json": {
      "titles": {
         "0": {
            "\u001epath": [
               "titlesById",
               "aca9317a-d813-4e35-8f22-428652c495c8"
            ],
            "rating": 0,
            "userRating": 0
         },
         "1": {
            "\u001epath": [
               "titlesById",
               "f40b6c24-be45-4969-b541-2f4491d1300a"
            ],
            "rating": 4,
            "userRating": 0
         },
         "2": {
            "\u001epath": [
               "titlesById",
               "656f9ed3-2973-4756-9f82-5d286244dfc7"
            ],
            "rating": 4,
            "userRating": 2
         }
      }
   }
}

To make things more confusing. When looking at the network traffic, I am getting errors. By it resolves somehow? Not really sure.

{
    "jsonGraph": {
        "titles": {
            "0": {
                "$type": "ref",
                "value": [
                    "titlesById",
                    "b697c926-cfd8-4564-8025-7252a3ec4599"
                ]
            },
            "1": {
                "$type": "ref",
                "value": [
                    "titlesById",
                    "7b833be2-ef51-46f4-9de6-77c427b8dce1"
                ]
            },
            "2": {
                "$type": "ref",
                "value": [
                    "titlesById",
                    "e32e733b-f21d-4842-a5f2-a7a21818f6a9"
                ]
            }
        },
        "titlesById": {
            "b697c926-cfd8-4564-8025-7252a3ec4599": {
                "Falcor.KeySet": {
                    "$type": "error",
                    "value": {
                        "message": null
                    }
                }
            },
            "7b833be2-ef51-46f4-9de6-77c427b8dce1": {
                "Falcor.KeySet": {
                    "$type": "error",
                    "value": {
                        "message": null
                    }
                }
            },
            "e32e733b-f21d-4842-a5f2-a7a21818f6a9": {
                "Falcor.KeySet": {
                    "$type": "error",
                    "value": {
                        "message": null
                    }
                }
            }
        }
    }
}

Does falcor.net support {keys} Pattern?

Hi,

I have been playing around with the sample code and was wondering if the current code supports {keys} pattern?

Falcor-Router

The {keys} Pattern

The {keys} pattern will match any valid key (string, number, boolean), or KeySet (an array of ranges or keys) and normalize the matching set of keys into an Array of keys.

For example…

genreList[0, 2..4, "length"]

…matched against…

genreList[{keys}]

…will produce the following Path Sets to be passed to the route handler:

["genreList", [0, 2, 3, 4, "length"]]

I was thinking that if it was supported, this route would work. But I can't get it working because I keep getting a parsing error from the client request. Any ideas?

Get["titlesById[{keys:ids}][{keys:props}]"] = async parameters => {
    var ids = parameters.ids;

    //...

    return Complete(results);
};

Reafactor ParserTests.cs

Right now https://github.com/falcordotnet/falcor.net/blob/master/src/Falcor.Tests/Server/Routing/ParserTests.cs is a little all over the place. Here are some suggestions for improvement:

  1. Refactor parsing tests into separate classes that test against IRouteParser and IPathParser interfaces that clearly show parser behavior and can be used to test alternate (perhaps more performant) implementations
  2. Create a separate test class for testing route matching behavior separate from parsing to more clearly illustrate and communicate intended route matching behavior

Add developer note

Hi,

I really like the project you have put together. I just wanted to share with you a little trouble I ran into when using this solution. I had a difficult time getting the simple helloWorld.json to run because of a dumb web.config setting.

The "standard" webconfig setting is

<handlers>
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

but it seems this doesn't work with the routering. It needs to have an extra "*"

<handlers>
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*.*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

Maybe, it would be nice to have a little section in the readme file or something. Just a thought. Hope this helps out someone else.

Implement PathSet parser

Often times pathsets need to be created for responses. This is currently aided by the IPathValueBuilder.

It would be nice to use path shorthand (similar to how routes are parsed today) for creating new pathsets. For example, "foo.bar.baz" would translate into a new FalcorPath("foo", "bar", "baz").

Parsing is already implemented for parsing routes in a similar manner, but the results are PathMatcher delegates, not FalcorPaths. The current path parsing implemented by IPathParser is intended for parsing PathSet arrays from the response query string.

SerializeItem doesn't support boolean

There is no allowance in ResponseSerializer.SerializeItem or SerializationHelper.SerializeItem for a value of type bool. The fix I discovered is to insert a new line in both that looks like:

        if (value is bool) return new JValue((bool)value);

Should I create a PR with code changes and test or will someone else do that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.