Code Monkey home page Code Monkey logo

nirvana's Introduction

Nirvana

Build Status Coverage Status GoDoc Go Report Card OpenTracing Badge

Nirvana is a golang API framework designed for productivity and usability. It aims to be the building block for all golang services at Caicloud. The high-level goals and features include:

  • consistent API behavior, structure and layout across all golang projects
  • improve engineering productivity with openAPI and client generation, etc
  • validation can be added by declaring validation method as part of API definition
  • out-of-box instrumentation support, e.g. metrics, profiling, tracing, etc
  • easy and standard configuration management, as well as standard cli interface

Nirvana is also extensible and performant, with the goal to support fast developmenet velocity.

Getting Started

Nirvana provides documentations in two languages to help you expore this framework. Note right now, only Chinese docs are kept up-to-date.

In addition, nirvana-practice provides a practical way for you to get familiar with Nirvana.

Features

  • API Framework based on Descriptors
  • Request Filter
  • Middleware
  • Validator
  • Plugins
  • API Doc Generation
  • Client Generation

Contributing

If you are interested in contributing to Nirvana, please checkout CONTRIBUTING.md. We welcome any code or non-code contribution!

Licensing

Nirvana is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

nirvana's People

Contributors

alswl avatar bbbmj avatar caicloud-bot avatar caitong93 avatar gaocegege avatar hezhizhen avatar jimexist avatar kdada avatar knight42 avatar lichuan0620 avatar liubog2008 avatar lsytj0413 avatar mephistommm avatar narrowizard avatar pendoragon avatar silva6 avatar supereagle avatar tskdsb avatar walktall avatar whalecold avatar wutz avatar wzqnls avatar xpofei avatar yejiayu avatar zoumo 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nirvana's Issues

Support 405, 406, 415

What is the issue about:

Methods support in Framework.

What happened:

nirvana doesn't support following methods right now:

  • 405 Method Not Allowed
  • 406 Not Acceptable
  • 415 Unsupported Media Type

What you expected to happen:

All commonly used method should be supported

Anything else we need to know:

@caicloud/review-framework who wanna take this?

better construction for flags

What is the issue about:
Improvement needed for StringFlag

screenshot 2017-12-13 17 49 17

What happened:
There are simply too many fields to be filled for StringFlag.

What you expected to happen:
Should be a builder or some other helper functions to fulfill default values.

Anything else we need to know:

GitHub page and example projects

What is the issue about:
GitHub pages should be set up along with two example projects:

  • hello world
  • todo app

What happened:
Nothing happened, I just figure that a more out-reaching stance this repo shall take.

What you expected to happen:
More open source usage, more tractions, etc.

Anything else we need to know:

  • skeleton #40
  • add status badge and add fork me at github button
  • choose a better theme
  • create CNAME and apply domain

Agenda for 10/25/2017 Meeting

Warm up

Where we are last time and why we are here. Welcome @yejiayu.

I expect the whole project to be ready around end of Q4.

Topics

Review Topics (5~10 min)

  • Prometheus
  • OpenAPI Gen

Remaining Topics (20 min)

  • Tracing
  • Configuration Management
  • API Validation

PR Discussion (40 min)

Action Items

We MUST decide the following items to end the meeting

CLI package is not output full help information.

What is the issue about:

CLI package is not output full help information.

What happened:

$ ./cli -h       
this is an cli example

Usage:
  example [flags]

Flags:
  -h, --help   help for example

What you expected to happen:

$ ./cli -h       
this is an cli example

Usage:
  example [flags]

Flags:
  -h, --help   help for example
  -l, --log      blabla
  -d, --dev    blabla

Anything else we need to know:

This is built from cli example. @zoumo

Agenda for 12/20/2017 Meeting

回顾过去

prev meeting

PR Updates

Milestone

https://github.com/caicloud/nirvana/milestone/1

把握现在

PRs going over

  • move /website #90
  • add golint #88

Issue assignment

  • #73 @kdada 12/22/2017
  • #75 @kdada 12/22/2017
  • #72 @liubog2008 01/01/2018
  • #67 @kdada 12/22/2017
  • #63 @kdada 12/22/2017

展望未来

  • Next Meeting Time:
    • 12/29/2017

logo design

We need a logo, something like this --> 🐦

Plan A:

image

Plan B

下面图片加上 A 的翅膀

image

Proposal and planning for API framework

Introduction

api framework, or http web framework, is a long standing engineering backlog across engineering teams. The proposal aims to shed some light on how we want to move forward. This is by no means a thorough design, we hope to gather enough feedback to get going. Feel free to comment.

Background

No guideline is provided at this moment to start up a new apiserver from scratch, results in a divergent approaches on setting up new web projects. No conventions enforced at framework level also results in bugs due to breaking apis, validation errors, etc. On the other hand, engineering effort is wasted on solving the same range of problems which should ideally be solved in an API framework.

Goal

  • Reduce api level errors and inconsistency
  • Improve engineering productivity via removing repeated work, adding code generation, etc
  • Adding new resource type should only require defining struct definition
  • Adding validation should only require declaring validation method as part of struct definition
  • Consistent behavior, structure and layout across all golang server projects
  • Out-of-box server instrumentation, e.g. metrics, tracing, profiling, etc

Proposal

Survey

Below is a short survey on existing projects:

  • kubernetes-admin style (go-restful)
    • routing wrapper around go-restful
    • a well-defined layout
    • count for 70% of all related projects
  • loadbalancer-admin style (gin)
    • use gin directly
    • no well-defined project layout
    • count for 20% of all related projects
  • liubo style (go-restful)
    • mirrors closely with kubernetes style
    • count for 10% of all related projects

Requirements

Following is all the required functionalities for our framework.

Routing, Request & Response

  • Routes mapping from request to function
    • support for path parameter (e.g. /api/v1/animals/{id})
    • support for query parameter (e.g. /api/v1/animals?type=dog)
    • support regex
  • Grouping Routes
    • routes can be grouped for better arragement, but doesn't have to be first class concept
  • Request/Response API object
    • to/from structs in json
    • easy access to path,query,header parameters
  • Middleware support
    • general middleware support is required for developer to add custom middleware
    • required default middleware: request logging, recovery, tracing
  • Contextual process chain and parameter injection
    • all handlers accepts a context value representing a request context
    • requset parameters can be validated and injected into handler, see below
  • API error convention
    • define canonical error code and type based on api convention
  • multipart/urlencoded form support (low priority)
  • file upload support (low priority)
  • grpc support (low priority)

Instrumentation

  • Provide default metrics at well-known endpoints for prometheus to scrape
    • need to define set of default metrics
  • Tracing should be provided by default to allow better troubleshooting
    • follow opentracing, which is industry standard
    • use jaeger as tracing system
  • Profiling can be enabled in debug mode for troubleshooting
    • use go profile

Validation

  • Provide default validation on api types with json, e.g. required, within a range, etc
  • Support custom validations defined by developers on api types
  • support validation on all parameters (path, query, etc)

Usability

  • A working project should be brought up with a few lines of code using the framework
  • Framework must follow engineering conventions to help developers focus on business logic
  • OpenAPI (swagger 2.0) specification can be generated automatically with no extra work
  • Provides a well-established layout conforming to golang project layout
  • Easy and standard configuration
  • A reasonable support for websocket

Performance

  • Performance is not a hard requirement for initial stage; but it should not introduce observable latency

None-requirements

A list of functionalities commonly seen in other frameworks that are not in our scope

  • https support. While it's not hard to serve https in go, https is out of scope since all services are expected to be running behind API gateway
  • html rendering, orm, etc. Let's stick it to a simple restful framework
  • testing. testing should be a different library

Design and Implementation

Project Timeline

  • Due 09.15: launch the project (@ddysher)
  • Due 09.23: draft feature set (@ddysher)
  • Due 09.29: finalize feature set and roadmap (@ddysher)
  • Due 12.01: check in most features (framework, cli, validation, metrics)
  • Due 12.20: check in all features, with reasonable test coverage (openapi, tracing)
  • Due 01.31: documentation, examples, website should be ready

Feature Design and Planning

Following is a list of planned features, their respective design and planning.

Meetings

Regular meetings will be held to discuss above topics.

Assignees

References

Agenda for 11/25/2017 Meeting

Topics

Status Updates (30 min)

  • OpenAPI Update
    • init pr in 12/15
  • Validation Update
    • not much work
    • init pr after basic framework (within 2 days)
  • Configuration Update
  • Instrumentation Update
    • need rewrite, pending issue
  • Tracing Update
    • what do we want to trace?
    • groups/123/configs -> groups/{gname}/configs
    • next Friday, tracing demo

PR Discussion (20 min)

Action Items

  • Next Meeting Time
    • 12/01/2017

investigate: contract driven, metadata-based property and/or automated testing

Relentless automation!

One shall see that given limited time and efforts, programmers tend to skip writing tests, and code quality plummets when a whole team joins such action. Tests should be automated, if possible.

There should be an investigation into how it can be done with limited efforts from application developers.

There's gopter that was inspired by Scalacheck (which was in turn inspired by Quickcheck). Without a strong type system, Golang automated testing can be done via contracts written in the shape of metadata, etc. and extracted and enforced by reflections.

Let's see where it leads us to ...

validator error format refine

What is the issue about:

Validator should have a refined error format.

What happened:

Currently, error returned from validator.v9 is not clearly enough.

What you expected to happen:

A well formatted error for nirvana.

Anything else we need to know:

Simplify errors package

Currently the errors package is a bit cumbersome:

errors.NotFound.NewFactory("not found", "").New("")

in order to make a simple not found error.

Suggest to use shortcuts or simply API structure.

Router regexp match

What is the issue about:

Router regexp

What happened:

Given:

"/article/{id}/{opts}"
"/article/{iffd}/edit"
"/files/{id}"
"/files/{id}:delete""

Call

"/article/111/edit"
"/files/789:delete"

What you expected to happen:

Want iffd:111

But Got opts:edit id:111

Want id:789

But Got id:789:delete

Anything else we need to know:

Tests trigger these can be found in #20

Cases ported from here

@kdada @ddysher

Agenda for 12/15/2017 Meeting

Topics

PR Updates

TODOs

  • Issue assignment
  • Deadline check
    • From proposal
    • Agree on v0.1.0 release timeline + items to fix
      • Create P1 issues @caicloud/review-framework
  • More examples (and assignment)
  • Proposal on project refinement @kdada []
    • Project organization
    • Package clean up
    • Definition for codegen

Action Items

  • Next Meeting Time

Better error message for unsupported mime type

What is the issue about:
need better error messages for unsupported mime types.

What happened:
got error message: no producer for content type text/plain

What you expected to happen:
show a list of supported mime types

Anything else we need to know:

Add gocyclo and golint into gometalinter

What is the issue about:
Adding more linter coverage.

What happened:
Golint and gocyclo could not be added because there are some pending fixes to be made.

What you expected to happen:
See lint errors.

Anything else we need to know:
@caicloud/review-framework esp. the router implementations, there are some complex functions that need to be refactored.

Throw at startup time instead of run time in case of wrong parameters

What is the issue about:
early throw in case of wrong parameters

What happened:
if I defined a handler function of type:

func(ctx context.Context, first int, after string)

while using definitions as

Parameters: []definition.Parameter{
					{
						Source: definition.Query,
						Name:   "after",
						Type:   reflect.TypeOf(""),
					},
					{
						Source:  definition.Query,
						Name:    "first",
						Type:    reflect.TypeOf(0),
						Default: 10,
					},
				},

then there's only an error thrown during request time.

But in fact, this check can be done at startup time.

What you expected to happen:

Anything else we need to know:

request for some built-in routes

request for some built-in routes:

e.g.

  • a helper to expose a /version route that can contain
    • version info e.g. git tag or sha digest
    • application name
    • other useful, public, non-security related info that'll help to identify the version
  • a helper to define metrics (e.g. hook up with Promethus) at /metrics
  • a ping method for load balance health check at /ping?

[Umbrella] Basic framework

Umbrella issue for tracking basic framework tasks, scope:

  • Research on existing solutions, pick one or create one
  • Proposal on basic framework implementation
  • Implementation: Routing, Multiplexing, Middleware, API error package, etc
  • Documentation
  • Testing

@kdada

Open Source License Missed

What is the issue about:

Open source license

What happened:

Missed

What you expected to happen:

Add the license to the repository and code.

Anything else we need to know:

application/json 4xx error when Accept is supplied

What is the issue about:
4xx error should be in json format if Accept: application/json header is specified

What happened:
For now only text/plain is returned

What you expected to happen:

Anything else we need to know:

pick a domain name

What is the issue about:

What happened:

What you expected to happen:

Anything else we need to know:

validator error is unreadable

What is the issue about:
While using validator, the error message is unreadable

What happened:

While using validator:

Operators: []definition.Operator{
							validator.Var("gte=0"),
						},

the error message is:

[query]first: Key: '' Error:Field validation for '' failed on the 'gte' tag

What you expected to happen:

Anything else we need to know:

[Umbrella] Configuration management

Umbrella issue for tracking configuration management tasks, scopes:

  • Research on cobra and viper
  • Research on how oss create wrapper around cobra (kubernetes, docker, etc)
  • Proposal on server start up options and configuration management
  • Standalone implementation (if necessary and possible) (initial PR @zoumo 11/14)
  • Integration with basic framework
  • Testing

@zoumo

better error message

Need better error message than:

panic: function parameters number does not adapt to definition

Agenda for 12/13/2017 Meeting

Topics

Previous action items

To-dos

  • Walk-through issues
  • Repository setup?
    • labels, milestones, etc
  • Others
    • errors? @walktall
    • log? @zoumo
    • framework done? if yes, next items? @kdada
      • router change 405, xxx
      • tracing matching routes? Fill issue
      • re-org

Action Items

  • Do we need a logo?
  • Next Meeting Time ??

[Umbrella] OpenAPI generation

Umbrella issue for OpenAPI generation tasks, scopes:

  • Research on kubernetes codegen
  • Introduction on codegen, background and how it works, etc (11/07 @liubog2008 )
  • Proposal on nirvana codegen
  • Integration with basic framework
  • Testing
  • Detailed documentation on how to generate API docs

@liubog2008

Agenda for 11/17/2017 Meeting

Topics

Updates (5 min)

  • OpenAPI Generation
    • thoughts after 11.10 seminar
    • @liubo is regularly busy, can we find another backup? @jimexist ?
  • Tracing
  • Random thought
    • should we also start planning testing framework?
  • Question from Slack
    • License
    • 框架暂时不支持 405 Method Not Allowed 406 Not Acceptable 415 Unsupported Media Type

PR Discussion (45 min)

  • Briefing about CI badge @jimexist (5min)
    • what badges have you added
    • what needs to be taken care of whiling we add more code
    • ref: #17, #18, #19
  • Check-in Test Coverage @walktall (10min)
    • what tests have you added and why do you think it's important
    • speak loud about the problems/caveats you found, and how team can help (and avoid making the same mistake in the future)
    • merge 🚀
  • Bug fix PR @kdada (0.1min)
    • please add tests after we merge test coverage PR
  • CLI package PR @zoumo (25min)
    • @caitong93 where is ur initial review?
    • First of all, tell us the story behind the name Mamba
    • PR Introduction and discussion
  • Basic framework example @kdada (25min)
    • PR Introduction and discussion

Next Step

Need to decide our next move.

  • Start OpenAPI? Yes
  • Start Validation? Yes
  • Start Tracing? Yes
  • Start Instrumentation? Yes
  • Next step for configuration? Fix and more docs

As a reminder, we need to have a working framework by end of Q4.

Action Items

  • Next Meeting Time
    • 11/24/2017

@caicloud/review-framework <-- Our new team. Use this when you want to ping folks.

Refactor exported methods

Now a lot of methods are exported in router package, which should instead be private. Keeping them private prevent library users from abusing internal states.

@kdada This issue needs triage.

[Umbrella] API validation

Umbrella issue for tracking API validation tasks, scopes:

  • Research on requirements, e.g. what kind of validation do we need
  • Research on existing solutions
  • Proposal or demonstration on how validation should work in nirvana
  • Integration with basic framework
  • Testing

@walktall

Agenda for 11/10/2017 Meeting

Topics

Updates (10 min)

  • Proposal
  • Generator
  • Configuration
  • API Framework

PR Check in (40 min)

Checkin Router implementation and create separate issues and assign to individuals (e.g. add minor features, documentation, test, etc). Also, other tasks like adding CI, etc.

Action Items

  • Tasks
    • Due 11.14: introduction to generator (README + PPT)
    • Due 11.17: example configuration management
    • Due 11.17: send out basic API framework
  • Next Meeting Time
    • 11/17/2017

better documentation for cli structs

request for better documentation for cli structs.

Current docs for e.g. persistent bears little information. I think there's need for better explanation for what persistent means for a cli argument.

  • better comment
  • a section in the docs

Proposal for refactoring nirvana

Why to refactor the framework

  1. We don't have a consistent design goal.
  • A framework package should not expose methods/functions which is from other packages.
  • A framework package provides interfaces to plug other packages rather than depend on those packages derectly.
  • Main packages of nirvana should reduce dependencies with other packages (promote interface).
  1. We don't have a consistent code style.
  • Replace SOME_CONST with SomeConst.
  • Hide unused vars and functions. #15
  1. Package paths is chaotic.
  2. Some packages contain limitations/bugs.
  • Match mehtod in router should support returning error. #28 #72
  • Helper functions for /version, /metrics, /ping. #51
  • Use nirvana/errors instead of go errors and refine error messages. #52 #59 #75
  • More validations. #60
  • More middlewares. #62
  • More debug info. #63
  • Make definition.Operator to be an interface. #68

The most important Goal: Users only need to import packages which they used.

Target directory tree

.
├── cli
├── cmd
│   ├── openapi-gen
│   ├── client-gen
│   └── nirvana
├── definition
├── docs
│   └── gitbook
├── errors
├── examples
│   ├── api-basic
│   ├── cli
│   └── stream
├── hack
│   ├── flag-gen
│   ├── license
│   └── boilerplate
├── log
├── middlewares
│   └── tracing
├── operators
│   └── validator
├── service
│   └── router
├── utils
│   ├── metrics
│   ├── probe
│   ├── profiling
│   └── version
│   └── openapi
└── nirvana.go

Framework Core Packages

  • definition: The package provides a self-described structure to define RESTful APIs.
  • errors: The package defines a structured error for users to create reasonable errors.
  • log: The package provides a glog style interface to output runtime info.
  • service: The package transforms definitions to http routers and executors (from web).
    • router: The package provides a general-purpose router to match executors for paths.
Dependency Graph
                       -----------
                       | service | 
                       -----------
       ---------------------|--------------------
       |                |           |           |
--------------    ----------    -------    ----------
| definition |    | router |    | log |    | errors |
--------------    ----------    -------    ----------

Framework Core Tools

  • cli: The package contains many utils to create commands.
  • cmd: The package contains commands to generate project-related codes.
    • openapi-gen: The command generates openapi document from definitions.
    • client-gen: The command generates go client by definitions.
    • nirvana: The command generates standard project structure (openapi-gen and client-gen could be merged into this command).
  • middlewares: The package contains all middlewares.
    • tracing: The package implements a middleware for opentracing.
  • operators: The package contains operators for handling API fields.
    • validator: The package provides a bundle of validators to validate request fields.
  • utils: The package contains many utils to help users to implement some functionalities quickly.
    • metrics: The util provides prometheus support.
    • probe: The util provides health check.
    • profiling: The util provides golang profiling.
    • version: The util provides http handler for application version.
    • openapi: The util provides functionalities for serving openapi pages.
  • nirvana: The package is the root package of nirvana. It provides configurations to install utils and can run a server for application.
Dependency Graph
                          -------
                          | cli | 
                          -------
       ----------------------|-------------------
       |                |                       |
-----------    --------------------    ---------------------
| spf13/* |    | stretchr/testify |    | fsnotify/fsnotify |
-----------    --------------------    ---------------------

                               -----------------
                               | middlewares/* | 
                               -----------------
       --------------------------------|-------------------------
       |                               |                        |
----------------------    ----------------------------    -------------
| nirvana/definition |    | prometheus/client_golang |    | others... |
----------------------    ----------------------------    -------------

                                ---------------
                                | operators/* | 
                                ---------------
       --------------------------------|------------------------
       |                               |                       |
----------------------    ---------------------------    -------------
| nirvana/definition |    | go-playground/validator |    | others... |
----------------------    ---------------------------    -------------

          -----------
          | utils/* | 
          -----------
       --------|-------
       |              |        
-----------    -------------
| nirvana |    | others... |
-----------    -------------

Framework Chores

  • docs: The package contains document for nirvana.
  • examples: The package provides many examples to explain how to use nirvana.
  • hack: The package contains some tools to maintain nirvana.

Plan

  1. Adjust directory structure.
  2. Refactor nirvana/log and nirvana/errors.
  • Implement a simple logger in nirvana/log.
  • Refine nirvana/errors.

👆 第一波


👇 第二波
  1. Refactor nirvana/service/router.
  • Add errors in nirvana/service/router.
  1. Refactor nirvana/definition and nirvana/service.
  • Enrich nirvana/definition.
  • Optimize nirvana/service.
  1. Refator middlewares/* and operators/*.
  • Implement nirvana/definition.Middlewares.
  • Implement nirvana/definition.Operators.
  1. Implement nirvana with plugin mode.
  • Implement nirvana configurations.
  • Implement nirvana server.
  1. Refactor and implement utils.
  2. Refactor cli.
  • Remove functions which expose from cobra and viper directly.
  1. Refactor cmd.
  2. Refine docs, examples, hack.

Agenda for 12/01/2017 Meeting

Topics

Updates

  • OpenAPI Update
  • Tracing Demo (15 min)
    • @yejiayu
    • Proposal or PR (next meeting)
  • Configuration Update (10 min)
  • Validation Update (10 min)
  • Instrumentation Update (10min)
  • Others
    • errors? @walktall
    • log? @zoumo
    • framework done? if yes, next items? @kdada
      • router change 405, xxx
      • tracing matching routes? Fill issue
      • re-org

Next Move

Action Items

  • Next Meeting Time
    • around 12/08/2017

[Umbrella] Tracing

Umbrella issue for tracking tracing tasks, scopes:

  • Research on tracing tools and client
  • Proposal on tracing, how it works in the framework
  • Integration with basic framework
  • Documentation
  • Testing

@ddysher @xiaoq17

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.