Code Monkey home page Code Monkey logo

rest's Introduction

SendGrid Logo

BuildStatus GoDoc Go Report Card Twitter Follow GitHub contributors MIT licensed

Quickly and easily access any RESTful or RESTful-like API.

If you are looking for the SendGrid API client library, please see this repo.

Announcements

All updates to this library is documented in our CHANGELOG.

Table of Contents

Installation

Supported Versions

This library supports the following Go implementations:

  • Go 1.14
  • Go 1.15
  • Go 1.16
  • Go 1.17

Install Package

go get github.com/sendgrid/rest

Setup Environment Variables

Initial Setup

cp .env_sample .env

Environment Variable

Update the development environment with your SENDGRID_API_KEY, for example:

echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env

With Docker

A Docker image has been created to allow you to get started with rest right away.

docker-compose up -d --build

# Ensure the container is running with 'docker ps'
docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED              STATUS              PORTS               NAMES
40c8d984a620        rest_go             "tail -f /dev/null"   About a minute ago   Up About a minute                       rest_go_1

With the container running, you can execute your local go scripts using the following:

# docker exec <container_name> <go command>
docker exec rest_go_1 go run docker/example.go
200
{
  "args": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Connection": "close",
    "Host": "httpbin.org",
    "User-Agent": "Go-http-client/1.1"
  },
  "origin": "86.180.177.202",
  "url": "https://httpbin.org/get"
}

map[Access-Control-Allow-Origin:[*] Access-Control-Allow-Credentials:[true] Via:[1.1 vegur] Connection:[keep-alive] Server:[gunicorn/19.9.0] Date:[Tue, 02 Oct 2018 18:20:43 GMT] Content-Type:[application/json] Content-Length:[233]]

# You can install libraries too, using the same command
# NOTE: Any libraries installed will be removed when the container is stopped.
docker exec rest_go_1 go get github.com/uniplaces/carbon

Your go files will be executed relative to the root of this directory. So in the example above, to execute the example.go file within the docker directory, we run docker exec rest_go_1 go run docker/example.go. If this file was in the root of this repository (next to README.exe, rest.go etc.), you would run docker exec rest_go_1 go run my_go_script.go

Quick Start

GET /your/api/{param}/call

package main

import "github.com/sendgrid/rest"
import "fmt"

func main() {
	const host = "https://api.example.com"
	param := "myparam"
	endpoint := "/your/api/" + param + "/call"
	baseURL := host + endpoint
	method := rest.Get
	request := rest.Request{
		Method:  method,
		BaseURL: baseURL,
	}
	response, err := rest.Send(request)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}

POST /your/api/{param}/call with headers, query parameters and a request body.

package main

import "github.com/sendgrid/rest"
import "fmt"

func main() {
	const host = "https://api.example.com"
	param := "myparam"
	endpoint := "/your/api/" + param + "/call"
	baseURL := host + endpoint
	Headers := make(map[string]string)
	key := os.Getenv("API_KEY")
	Headers["Authorization"] = "Bearer " + key
	Headers["X-Test"] = "Test"
	var Body = []byte(`{"some": 0, "awesome": 1, "data": 3}`)
	queryParams := make(map[string]string)
	queryParams["hello"] = "0"
	queryParams["world"] = "1"
	method := rest.Post
	request = rest.Request{
		Method:      method,
		BaseURL:     baseURL,
		Headers:     Headers,
		QueryParams: queryParams,
		Body:        Body,
	}
	response, err := rest.Send(request)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}

Usage

How to Contribute

We encourage contribution to our projects, please see our CONTRIBUTING guide for details.

Quick links:

About

rest is maintained and funded by Twilio SendGrid, Inc. The names and logos for rest are trademarks of Twilio SendGrid, Inc.

Support

If you need help using SendGrid, please check the Twilio SendGrid Support Help Center.

License

The MIT License (MIT)

rest's People

Contributors

ajloria avatar aleien avatar alimasyhur avatar alxshelepenok avatar ciceropablo avatar daniloff200 avatar eshanholtz avatar gabrielclima avatar garethpaul avatar giovannygb avatar gliptak avatar gr8shivam avatar jennifermah avatar johejo avatar liamrosenfeld avatar mbernier avatar mptap avatar mrmuskrat avatar obahareth avatar pushkyn avatar radlinskii avatar sadliak avatar shwetha-manvinkurke avatar someone1 avatar succo avatar thepriefy avatar thinkingserious avatar twilio-ci avatar twilio-dx avatar vaskoz 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  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

rest's Issues

[Feature Request] Can't pass context to requests

Issue Summary

Currently, there is no way to pass the context along with any requests without manually building the request ourselves. It should be trivial to introduce a SendWithContext type function which is exactly like the original, but takes a context.Context as the first parameter and sets it on the built http.Request

Something like:

func (c *Client) SendWithContext(ctx context.Context, request Request) (*Response, error) {
	req, err := BuildRequestObject(request)
	if err != nil {
		return nil, err
	}
	req = req.WithContext(ctx)

	// Build the HTTP client and make the request.
	res, err := c.MakeRequest(req)
	if err != nil {
		return nil, err
	}

	// Build Response object.
	return rest.BuildResponse(res)
}

The alternative is to switch to the idiomatic http Request/Response types throughout but it looks like that issue/PR has been on hold for over a year? This seems like it'd be much faster to incorporate (no breaking changes introduced!)

Change function signature from rest.API to rest.Send

Issue Summary

"API" reads to me like it's constructing an API structure based on some description (such as swagger or raml), and that method calls on that type would actually produce network requests. Based on the name "API", I wouldn't necessarily consider it to "do" anything, since it's not a verb

via @extemporalgenome

Increase code coverage

Issue Summary

Current code coverage is 91.2%. We can do better.

Steps to Reproduce

  1. go test -v ./... results in the following:
rest git:(master) go test -cover
PASS
coverage: 91.2% of statements
ok  	github.com/sendgrid/rest	0.045s

This is primarily an improvement. Additional testing did find an unchecked error due to a bad request causing a panic in the library.

The tests added by 8e0c097 resulted in the following panic:

rest git:(8e0c097) go test
--- FAIL: TestBuildBadRequest (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x126288a]

goroutine 7 [running]:
testing.tRunner.func1(0xc4200fe2d0)
	/Users/vasko/code/go/src/testing/testing.go:734 +0x29a
panic(0x12af500, 0x14927d0)
	/Users/vasko/code/go/src/runtime/panic.go:502 +0x266
github.com/sendgrid/rest.BuildRequestObject(0x1308b2f, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, ...)
	/Users/vasko/go/src/github.com/sendgrid/rest/rest.go:79 +0x1aa
github.com/sendgrid/rest.TestBuildBadRequest(0xc4200fe2d0)
	/Users/vasko/go/src/github.com/sendgrid/rest/rest_test.go:53 +0x98
testing.tRunner(0xc4200fe2d0, 0x131d240)
	/Users/vasko/code/go/src/testing/testing.go:769 +0xc0
created by testing.(*T).Run
	/Users/vasko/code/go/src/testing/testing.go:812 +0x2b1
exit status 2
FAIL	github.com/sendgrid/rest	0.027s

and the panic was fixed by checking for the error in df76d1a

Add a .env_sample file

Our preference is that users have an environment file when using the SendGrid API, because it is less likely that someone would commit their credentials to github.

Please make a couple changes:

  • make a .env_sample file that contains: export SENDGRID_API_KEY=''
  • make (or add) a .gitignore file and include .env
  • add instructions to the README file about how to copy .env_sample to .env and add the API Key

Add/Update Badges on README

Similar to what was done on the SendGrid node README:

  • put the logo at the top of the list
  • Add License like so
  • make sure the other badges are available like so:
![SendGrid Logo](https://uiux.s3.amazonaws.com/2016-logos/email-logo%402x.png)

For the following, make sure the correct repo is linked!
For email notifications, you can change the "nodejs" to the language of this repo (e.g. java, python, ruby, php, csharp, go, etc)

[![BuildStatus](https://travis-ci.org/sendgrid/sendgrid-nodejs.svg?branch=master)](https://travis-ci.org/sendgrid/sendgrid-nodejs)
[![Email Notifications Badge](https://dx.sendgrid.com/badge/nodejs)](https://dx.sendgrid.com/newsletter/nodejs)
[![npm](https://img.shields.io/npm/l/express.svg)]()
[![Twitter Follow](https://img.shields.io/twitter/follow/sendgrid.svg?style=social&label=Follow)](https://twitter.com/sendgrid)
[![GitHub contributors](https://img.shields.io/github/contributors/sendgrid/sendgrid-nodejs.svg)](https://github.com/sendgrid/sendgrid-nodejs/graphs/contributors)

Thank you and happy #Hacktoberfest!!

Add a USAGE.md file

Usage files are really nice when they exist in a repo, because it makes it really obvious where to look for information about how to use this tool. It can be frustrating when you expect this file to be there and it's not.
Please add a USAGE.md file, you can see an example of this
here

Please make sure you modify the file for this repo (hint: Most of this information should be in the README file)

Take a rest in this docker container

Issue Summary

It is really nice to be able to develop locally inside a docker container! Please dockerize this repo!

  • You can probably use the Dockerfile for sendgrid-go
  • Please setup docker-compose to use a local volume for the library files (this is currently different from sendgrid-go)
  • Please add information to the README and USAGE files about how to startup the container

Build is broken

Issue Summary

The build is broken right now. I completed the following fixes in individual commits.

* 96b32b0 2018-04-06 | fix godoc comments for some functions (HEAD -> fixBuild, vaskoz/fixBuild) [Vasko Zdravevski]
* 9968371 2018-04-06 | fix golint issue testingApi -> testingAPI [Vasko Zdravevski]
* 90ba74a 2018-04-06 | fix expected files in TestRepoFiles [Vasko Zdravevski]
* d88e957 2018-04-06 | update year to 2018 to fix TestLicenseYear [Vasko Zdravevski]
* 8430197 2018-04-06 | go fmt ./... formatting fixes [Vasko Zdravevski]
* ca669a4 2018-04-06 | fix gometalinter issue of an unchecked error [Vasko Zdravevski]
* e29d0ac 2018-04-06 | add go 1.10.x runtime to travis.yml [Vasko Zdravevski]

Steps to Reproduce

  1. Just check the TravisCI build.

Technical details:

  • Added Go 1.10 runtime for the travis ci build.

Add a unittest to check the license.md file date range

The end year in the license file should be "this year" and this should be checked on every run of the tests. If the end year is no correct, fail the test.
example:

Copyright (c) 2012-2016 SendGrid, Inc.
It is 2017, so this should be:
Copyright (c) 2012-2017 SendGrid, Inc.
and the test should fail.
--done

Add Go Report Card

Issue Summary

Add the following to the README badges, right after the GoDoc badge

[![Go Report Card](https://goreportcard.com/badge/github.com/sendgrid/rest)](https://goreportcard.com/report/github.com/sendgrid/rest)

Use go's http.Headers, http.Request and url.Values types

Hi @thinkingserious, here are a few things I noticed:

  • Headers are modeled as map[string]string. Why not use the stdlib http.Headers for that instead?
  • The rest.Request type is similar to the stdlib http.Request type. Using the stdlib types could make the library more easy to integrate with other code. If you do that, then
  • Query params is modeled as map[string]string, usually in Go code this is done with the url.Values type

This code doesn't require a type assertion:

    var f interface{}
    err = json.Unmarshal(b, &f)
    if err != nil {
        fmt.Println(err)
    }
    m := f.(map[string]interface{})
    apiKey := m["api_key_id"].(string)

You can do this instead:

var f struct { 
  APIKeyID string `json:"api_key_id"`
}

err = json.Unmarshal(b, &f)

The only difference I see between the stdlib HTTP client and this one is that it returns a string for the response body instead of an io.Reader. Otherwise the overall level of complexity feels about the same as the stdlib client.

Auto-generate the release notes upon release

Issue Summary

For every release, we hand craft the release notes on GitHub, now we would like to automate this process. Please see the existing release notes for an example. The contents of the release notes are generated from the CHANGELOG.md file. Here is the documentation for updating the release notes via the GitHub API.

Acceptance Criteria

  • A script, which when run, creates a release note update based on the last deployed release

Create a Use Cases Directory

Due to the success we have seen from hacktoberfest, we are seeing more people create use cases. This is amazing!
We want to make sure that everyone can find them. Please help us to break up this file and make it easier to read and manage:

  • Create a Use Cases Directory
  • Put a README.md in this directory
  • Make a file in the new directory for each individual Use Case from USE_CASES.md, copy the content to this file
  • For each file you've created, link to it from the README you created
  • Organize the links in the README by type
  • Make sure the names of the files you created are related to the Use Case
    Thank you!

Hacktoberfest: SendGrid Current Status

SendGrid DX team current status:

  • Wow
  • OMG
  • THANK YOU

Hacktoberfest 2017 has completely blown us away. We have had over 900 pull requests from over 300 contributors all in the last 30 days. That is more PRs than we normally get in 2 years!
We are actively working to review, comment, and/or merge as many PRs as we possibly can as quickly as we can.

We are currently working on “intaking” all the PRs that have come in, oldest first (we have about 400 remaining to go through). We are making sure that each PR we review is one we have a chance of merging - there have been a couple spammy items that came through. Due to the massive influx of requests so far, @thinkingserious and @mbernier have been working nights and weekends all month just to keep up! We’re not even mad, this is amazing!

Hey, that’s great for you - but what about my shirt!

If you have signed the CLA before 11/1, but haven’t had a PR merged yet, do not despair! We know we are behind on even just commenting on every PR to show you that we received it (something we typically do). If you submitted a mergeable (non-spam, actually adds value to the project) PR during October 2017, we will grant access to this page to redeem your shirt, sticker, and hacker pin. Next year, we will be sure to communicate this information sooner. We are sorry for any confusion we have caused. We appreciate those of you who have reached out to find out what’s going on!

What can I do to help move things along?

Have you signed the CLA yet?
We can only merge items from contributors who signed the CLA

Can you help another contributor?
If you can identify potential problems, add suggestions, or even leave a comment with your review of another PR (Looks good to me! Or I approve this change), that would help us review those PRs much faster, making it easier to get to your PR.

Do you even write tests, friend?
If you see a place where we could have a test to validate a piece of functionality, add it in. We know We know! It’s just another PR we have to review and merge. You’re right, it is! However, the more tests we have, the earlier our CI tool can catch issues, saving us a review as well as back and forth time.

@emisanada, @gabrielclima, @janczer, @mrmuskrat, @thepriefy, @tuckerrc, @vaskoz

Recent change to sendgrid/rest is breaking sendgrid/sendgrid-go

Issue Summary

Recent change to sendgrid/rest is breaking sendgrid/sendgrid-go. Ran
go get github.com/sendgrid/sendgrid-go

getting errors when building:
../../vendor/github.com/sendgrid/sendgrid-go/sendgrid.go:49:2: not enough arguments to return

../../vendor/github.com/sendgrid/sendgrid-go/sendgrid.go:49:22: DefaultClient.API undefined (type *rest.Client has no field or method API)

Steps to Reproduce

  1. go get github.com/sendgrid/sendgrid-go
  2. go build
  3. errors

rest.Client.API function does not exist anymore and is still being used by sendgrid/sendgrid-go.

Technical details:

  • package: github.com/sendgrid/sendgrid-go version: v3.4.1
  • go version go1.9 darwin/amd64

Add a .codeclimate.yml file to this repo

It is possible to configure how CodeClimate looks at a repository.
These Docs explain how this is done. Please create an appropriate .codeclimate.yml for this repo. It should test the main language of the repo and run tests.

Update .md files for SEO-ness

We received an awesome PR for #hacktoberfest on our ruby library
We would love to see the same thing on the README in this repo as well.
Please replace the "-" with "_" in README, CONTRIBUTING, USE_CASES, USAGE files.

Thanks and happy Hacktoberfest!!

Auto-generate the CHANGELOG.md file upon release

Issue Summary

For every release, we currently hand craft a CHANGELOG.md update, now we would like to automate this process. Please see the existing CHANGELOG.md for formatting structure.

Acceptance Criteria

  • A script, which when run, creates a CHANGELOG.md update based on any merged PRs since the last release.

Document that a custom HTTP client should be used when deploying to AWS

rest/rest.go

Line 43 in 5a76b29

var DefaultClient = &Client{HTTPClient: http.DefaultClient}

For reasons I still haven't figured out, the fact that the library uses http.DefaultClient for the client in calls to the API can result in the Authorization: Bearer <API Key> header being replaced by one determined by AWS. This doesn't happen all the time (in our case, it was always working in our dev server, but always failing on our prod server - maybe it's a race condition to set up the DefaultClient):

Authorization:[AWS4-HMAC-SHA256 Credential=AKIATH.../us-east-1/es/aws4_request, SignedHeaders=accept;content-type;date;host;x-amz-date, Signature=368af...]

I was able to fix the problem by replacing your library with a raw net/http request, and using a custom http.Client:

client := &http.Client{Timeout: 3 * time.Second}

This is now working in production.

BuildRequestObject should call AddQueryParameters

    // Add any query parameters to the URL.
    if len(request.QueryParams) != 0 {
        request.BaseURL = AddQueryParameters(request.BaseURL, request.QueryParams)
    }

This snippet should live inside BuildRequestObject

Document new Git workflow in CHANGELOG.md

Issue Summary

We want to update our git workflow to function more like Gitflow. We need to update the CONTRIBUTING.md file and PULL_REQUEST_TEMPLATE to direct contributors to fork/branch off the development branch and to merge their PRs with the development branch. Once this issue is complete, we will be creating the development branch and making that branch the default. This is part of a larger strategy to execute releases for this SDK on a predictable cadence.

Acceptance Criteria

  • Update CONTRIBUTING.md documentation, explaining the process of forking and branching off the development branch and submitting PRs agains the development branch.
  • Update PULL_REQUEST_TEMPLATE with the same addition to the CONTRIBUTING.md documentation.

Create first time contributor documentation

Issue Summary

Our open sourced documentation has a great first time contributor page that we wish to duplicate here.

Acceptance Criteria

  • We have a file in the root directory called first-timers.md or similar that helps a first time contributor make their first PR (please use our CONTRIBUTOR.md file for inspiration as well as this page)
  • We provide a link to tasks with the labels "difficulty: easy" and "status: help wanted" (example query) to all the repos listed here, please scroll to the bottom.

Add unittest to check for specific repo files

This repo should have the following list of files included:

  • ./Docker or docker/Docker
  • ./docker-compose.yml or ./docker/docker-compose.yml
  • ./.env_sample
  • ./.gitignore
  • ./.travis.yml
  • ./.codeclimate.yml
  • ./CHANGELOG.md
  • ./CODE_OF_CONDUCT.md
  • ./CONTRIBUTING.md
  • ./.github/ISSUE_TEMPLATE
  • ./LICENSE.md
  • ./.github/PULL_REQUEST_TEMPLATE
  • ./README.md
  • ./TROUBLESHOOTING.md
  • ./USAGE.md
  • ./USE_CASES.md

This PR is only asking for tests of the existence of these files, if the files do not exist when you run the tests - do not worry about the tests not passing. We will identify this and create a new PR for the issue.
Thank you!

Add our Developer Experience Engineer career opportunity to the README

Issue Summary

The role of Developer Experience Engineer just became available and we want to announce it in the README. Here is the copy:

If you're a software engineer who is passionate about #DeveloperExperience and/or #OpenSource, this is an incredible opportunity to join our #DX team as a Developer Experience Engineer and work with @thinkingserious and @aroach! Tell your friends :)

Acceptance Criteria

  • The above announcement is added to the Announcements section of this README

Implementation of error Interface

A implementation of error Interface is helpful us. (https://blog.golang.org/error-handling-and-go)

Suggestion

// RestError is a struct for an error handling.
type RestError struct {
    Response *Response
}

// Error is a implementation of error interface.
func (e *RestError) Error() string {
    return e.Response.Body
}

How to Use

func doSomething() error {
    response, err := sendgrid.API(request)
    if err != nil {
        return err
    }
    if response.StatusCode != 201 {
        restErr := &rest.RestError{
            Response: response,
        }
    return restErr
    }
    return nil
}

///////

err := doSomething()
if restErr, ok := err.(*rest.RestError);ok {
    if restErr.Response.StatusCode == 400 {
            fmt.Println("Bad Request")
    } else if restErr.Reponse.StatusCode == 500 {
            fmt.Println("Internal Server Error")
    }
}

What do you think? If you also feel useful, I want to send PR.

Maybe RestError should be implement in sendgrid/sendgrid-go

Require conformance to style standards

Issue Summary

In the CONTRIBUTING.md file there is a section on Style Guidelines & Naming Conventions. Please review and implement a check in Travis CI. If there are any style errors, either fix or create a rule to exclude the error.

Before writing any code, we suggest you review our CONTRIBUTING.md file and propose your solution for discussion here in the comments. Thank you!

Aceptance Criteria

  • TravisCI checks that the code conforms to our Style Guidelines & Naming Conventions as defined in our CONTRIBUTING.md file
  • tests pass locally, in Travis CI and using Docker

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.