GithubHelp home page GithubHelp logo

fdoc's Introduction

fdoc: Documentation format and verification

High-quality documentation is extremely useful, but maintaining it is often a pain. We aim to create a tool to facilitate easy creation and maintenance of API documentation.

In a Rails or Sinatra app, fdoc can help document an API as well as verify that requests and responses adhere to their appropriate schemata.

Outside a Rails or Sinatra app, fdoc can provide a common format for API documentation, as well as the ability to generate basic HTML pages for humans to consume.

fdoc is short for Farnsdocs. They are named for everybody's favorite, good news-bearing, crotchety old man, Professor Farnsworth.

Professor Farnsworth

Usage

In a Rails app

Add fdoc to your Gemfile.

gem 'fdoc'

Tell fdoc where to look for .fdoc files. By default, fdoc will look in docs/fdoc, but you can change this behavior to look anywhere. This fits best in something like a spec_helper file.

require 'fdoc'

Fdoc.service_path = "path/to/your/fdocs"

# Configure how Fdoc decides a successful response
Fdoc.decide_success_with do |response, status|
 status.to_i < 400
end

fdoc is built to work around controller specs in rspec, and provides Fdoc::SpecWatcher as a mixin. Make sure to include it inside your top level describe.

require 'fdoc/spec_watcher'

describe MembersController do
  include Fdoc::SpecWatcher
  # ...
end

To enable fdoc for an endpoint, add the fdoc option with the path to the endpoint. fdoc will intercept all calls to get, post, put, and delete and verify those parameters accordingly.

context "#show", fdoc: 'members/list' do
  # ...
end

fdoc also has a scaffolding mode, where it attemps to infer the schema of a request based on sample responses. The interface is exactly the same as verifying, just set the environment variable FDOC_SCAFFOLD=true.

FDOC_SCAFFOLD=true bundle exec rspec spec/controllers

For more information on scaffolding, please see the more in-depth fdoc scaffolding example.

In a Sinatra app

Add fdoc to your Gemfile.

gem 'fdoc'

Tell fdoc where to look for .fdoc files. By default, fdoc will look in docs/fdoc, but you can change this behavior to look anywhere. This fits best in something like a spec_helper file.

require 'fdoc'

Fdoc.service_path = "path/to/your/fdocs"

fdoc is built to work around your Sinatra app specs in rspec, and provides Fdoc::SpecWatcher as a mixin. Make sure to include it inside your top level describe.

require 'fdoc/spec_watcher'

describe Sinatra::Application do
  include Rack::Test::Methods
  include Fdoc::SpecWatcher

  def app
    Sinatra::Application
  end
end

Outside a Rails App

fdoc provides the fdoc convert script to transform a directory of .fdoc files into more human-readable HTML.

In this repo, try running:

bin/fdoc convert ./spec/fixtures --output=./html
Options:
  -o, [--output=OUTPUT]                # Output path
  -u, [--url-base-path=URL_BASE_PATH]  # URL base path
  -f, [--format=FORMAT]                # Format in html or markdown, defaults to html
                                       # Default: html
  -t, [--templates=TEMPLATES]          # Directory with override templates

Example

.fdoc files are YAML files based on JSON schema to describe API endpoints. They derive their endpoint path and verb from their filename.

Here is docs/fdoc/members/list-GET.fdoc:

description: The list of members.
requestParameters:
  properties:
    limit:
      type: integer
      required: no
      default: 50
      description: Limits the number of results returned, used for paging.
responseParameters:
  properties:
    members:
      type: array
      items:
        title: member
        description: Representation of a member
        type: object
        properties:
          name:
            description: Member's name
            type: string
            required: yes
            example: Captain Smellypants
responseCodes:
- status: 200 OK
  successful: yes
  description: A list of current members
- status: 400 Bad Request
  successful: no
  description: Indicates malformed parameters

If we run a test against our members controller with an undocumented parameter, offset, we'll get an error.

Our spec file, spec/controllers/members_controller_spec.rb looks like:

require 'fdoc/spec_watcher'

describe MembersController do
  context "#show", fdoc: "members/list" do
    it "can take an offset" do
      get :show, {
        :offset => 5
      }
    end
  end
end

We run:

bundle exec rspec spec/controllers/members_controller_spec.rb

And since offset is undocumented, fdoc will fail the test:

Failures:

  1) MembersController#show can take an offset
     Failure/Error: get :show, { :offset => 5 }
     JSON::Schema::ValidationError:
       The property '#/' contains additional properties ["offset"] outside of the schema when none are allowed in schema 8fcac6c4-294b-56a2-a3de-9342e2e729da#
     # ./spec/controllers/members_controller_spec.rb:5:in `block (3 levels) in <top (required)>'

If we run the same spec in scaffold mode, it passes and fdoc will write changes to the correspoding .fdoc file:

FDOC_SCAFFOLD=true bundle exec spec/controllers/members_controller_spec.rb

The diff looks like:

diff --git a/docs/fdoc/members/list-GET.fdoc b/docs/fdoc/members/list-GET.fdoc b2e3656..dfa363a 100644
--- a/docs/fdoc/members/list-GET.fdoc
+++ b/docs/fdoc/members/list-GET.fdoc
+    offset:
+      description: ???
+      required: ???
+      type: integer
+      example: 5

Notice how it infers a type, and copies an example, but leaves description and required blank. These fields are best left to humans to decide.

Goals

  • Client engineers should be able to participate in documenting an API and keeping it up to date.
  • Server engineers should be able to test their implementations.
  • The documentation should be as close to the code as possible.
    • Branches, reviews, and merges are the appropriate way to update the docs.
    • Experimental drafts should just live on branches and never get merged into master.
  • Specification alone is not enough, there needs to be room for discussion.

Contributing

Just fork and make a pull request! You will need to sign the Individual Contributor License Agreement (CLA) before we can merge your code.

fdoc's People

Contributors

chischaschos avatar chris-baynes avatar chrishunt avatar chrisk avatar daicoden avatar damncabbage avatar emily avatar etdebruin avatar harlow avatar jackdanger avatar jasonayre avatar jawspeak avatar jessieay avatar joonas avatar mcollina avatar mikelikespie avatar ohrite avatar rjrjr avatar rudle avatar square-build-bot avatar strathmeyer avatar vkotovv avatar xaviershay avatar zachmargolis 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

fdoc's Issues

Dynamic endpoints

Is it possible to have dynamic endpoint urls?
For example you have a resource User, then your documented show action could look like: /users/5
rather than the current path: /users with example request: { id: 5 }

What would also be great is to have services with a dynamic basePath, that specify the dynamic params in the .service file.

Any plans to implement either of those?

Test suite passing?

I tried running the specs from master and I'm seeing a little red. Maybe one of my gem versions is incorrect?

Failures:

  1) Fdoc::EndpointScaffold#consume_response for succesful responses produces a valid JSON schema for the response
     Failure/Error: JSON::Validator.validate!(subject.response_parameters, response_params).should be_true
     NoMethodError:
       undefined method `each' for "???":String
     # ./spec/fdoc/endpoint_scaffold_spec.rb:223:in `block (4 levels) in <top (required)>'

  2) Fdoc::Endpoint#consume_request complex examples is successful
     Failure/Error: subject { endpoint.consume_request(params) }
     NoMethodError:
       undefined method `each' for false:FalseClass
     # ./lib/fdoc/endpoint.rb:19:in `consume_request'
     # ./spec/fdoc/endpoint_spec.rb:37:in `block (3 levels) in <top (required)>'
     # ./spec/fdoc/endpoint_spec.rb:113:in `block (4 levels) in <top (required)>'

  3) Fdoc::Endpoint#consume_request complex examples with no optional keys is successful
     Failure/Error: subject { endpoint.consume_request(params) }
     NoMethodError:
       undefined method `each' for true:TrueClass
     # ./lib/fdoc/endpoint.rb:19:in `consume_request'
     # ./spec/fdoc/endpoint_spec.rb:37:in `block (3 levels) in <top (required)>'
     # ./spec/fdoc/endpoint_spec.rb:124:in `block (5 levels) in <top (required)>'

Let me know if anything jumps out to you here. I'd like to get it green before creating any PRs.

Error with date-time in response

After generating a template for a controller action (and tests passing), I run the specs again. I have some JSON keys 'created-at' and 'updated-at' that point to date-time strings. Fdoc is is giving an error for one of these fields.

I can confirm that the string is in the ISO8601 format. I parsed the response, converted the string to a DateTime object, then back to ISO8601 format and it's the same exact string I started with.

JSON::Schema::ValidationError:
       The property '#/product-permissions/0/created-at' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss.ssZ in schema ae989cdc-e527-5940-9752-73dbd0160fee#

Running rspec with FDOC_SCAFFOLD=true raises Errno::ENOENT

Running FDOC_SCAFFOLD=true bundle exec rspec spec/controllers/api/v1/ results in the following error for every test:

Api::V1::PaystubsController#index one of the payroll_items include flsa_status
     Failure/Error: get :index, employee_id: employee.id, format: 'json'
     Errno::ENOENT:
       No such file or directory - /Users/chrismaddox/workspace/zenpayroll/docs/fdoc/paystubs/index-GET.fdoc
  • the docs/fdoc/paystubs directory does exist
  • I put require 'fdoc/spec_watcher' at the top of the test
  • include Fdoc::SpecWatcher is the first line inside describe Api::V1::PaystubsController

The tests pass fine without Fdoc::SpecWatcher included.

If I touch the file that it says is missing, every test fails with a new error:

     Failure/Error: get :index, employee_id: employee.id, format: 'json'
     TypeError:
          no implicit conversion from nil to integer

How can I get a basic Fdoc scaffolding for my API endpoints?

Nested resources handling

Hi, how do you think we should handle nested resources, by nested I mean things like:

/resource1/:param1/resource2

Would you simply suggest create an fdoc file following that name?

Regards

ED

Show multiple responses

How do you show mutltiple response examples? I want to show a successful response and an error response. But the scaffold seems to mix all the responses from my tests into one big hash.

Example:

Valid Response:
{ response: { id: 1234, name: John } }

Error Response:
{ error: invalid_resource, error_description: "The current resource was deemed invalid.", messages: { name: ["can't be blank"] } }

fdoc error when converting to html in rails

 - docs/fdoc              
  - blog.fdoc.meta  
  - posts                   
    - POST.fdoc   
    - posts.fdoc.service
  - comments
      - POST.fdoc 
      - comments.fdoc.service
 - docs/fdoc              
    - blog.fdoc.meta                   
    - posts-POST.fdoc   
    - posts.fdoc.service   
    - comments-POST.fdoc 
    - comments.fdoc.service

docs/fdoc/blog.fdoc.meta contains

   name: blog
   services:
   - ../fdoc/posts
   - ../fdoc/comments

When i try to convert from fdoc to html i get

fdoc-0.3.2/lib/fdoc/presenters/meta_service_presenter.rb:43:in block in endpoints': undefined method<<' for nil:NilClass (NoMethodError)

If i rename posts/POST.fdoc to something else like posts/fsfadsfad-POST.fdoc it works fine.

if i dont include fdoc.meta file, it produces endpoints correctly but without the names of posts and comments services listed.

What am i doin wrong here?...

fdoc_to_html issues

When running

fdoc_to_html ./docs/fdoc ./html

this happens:

/gems/fdoc-0.2.6/lib/fdoc/presenters/html_presenter.rb:38:in `render_json': undefined method     `pretty_generate' for JSON:Module (NoMethodError)

Path variables?

Is there a way to use FDOC to document path variables?

requestParameters works if the parameters are passed in the body of the JSON, but what if parameters are passed as part of the URL?

An example: http://localhost:9292/api/postcodes/:country/:postcode

For this example, I'd like to document the acceptable format of :country and :postcode, as these are path variables.

Dynamic keys?

I have a json response that includes a couple of objects that serve as lookups for the main response fragment:

Example:

{
   "books": [
       {
            "id":  12,
            "name": "book1",
            "author_id": 1
       },
       {
            "id": 125,
            "name": "book125",
            "author_id": 4
       }
   ],
   "authors": {
       "1": { ....},
       "4": {.....}
   }
}

Instead of authors being an array, it's instead an object the author id as the key. This makes it really easy for clients to parse into their native data structures (Dictionary, Hash, whatever) and do quick lookups when building up the response objects.

The main reason is that there might be a ton of books by the same author and this severely cuts down in the overall response size by eliminating the duplication.

Now when I bring fdoc in, it fails because I don't really have a way to describe this structure.

I'm thinking of something like this:

   authors:
          description: A lookup of the authors represented in the book list.
          required: false
          type: object
          properties:
            __id__:
              property_type: dynamic 
              type: object
              properties:
                id:
                  description: the id of the author
                  type: integer
                  example: 24512

Here the __id__ is perhaps a convention that this property is special, and the property_type attribute set to dynamic could tell the validator to not just treat the attribute at face value.

If this is not currently possible to validate with fdoc, I'd love to know. Failing that is there a way to ignore an entire fragment (but validate the rest) so that my tests don't fail for these endpoints?

Gem release?

I was having some issues generating docs with fdoc this morning. When I went source diving, I noticed that my local files did not match what is on GitHub. Specifically, the check for RSpec 3 here:

if RSpec.respond_to?(:current_example) # Rspec 3

When I went to compare the git history and gem releases, I saw that the gem was last released in November 2011 https://rubygems.org/gems/fdoc

Is there a reason for this? A new release would be awesome!

Mention Ruby version in Readme

We tried to run fdoc on a machine with Ruby 2.0 and it failed with the following stack trace. Then it worked with Ruby 1.8.7 installed. Maybe it should be explicitly stated that you should use Ruby < 2.0 to run fdoc.

(erb):46:in `concat': incompatible character encodings: UTF-8 and US-ASCII (Encoding::CompatibilityError)
from (erb):46:in `get_binding'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/erb.rb:849:in `eval'
from /System/Library/Fram
eworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/erb.rb:849:in `result'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/presenters/base_presenter.rb:23:in `render_erb'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/presenters/endpoint_presenter.rb:12:in `to_html'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:58:in `block (4 levels) in convert_to_html'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:57:in `each'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:57:in `block (3 levels) in convert_to_html'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:56:in `each'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:56:in `block (2 levels) in convert_to_html'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor/actions.rb:184:in `block in inside'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:125:in `chdir'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:125:in `cd'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor/actions.rb:184:in `inside'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:85:in `inside_service_presenter'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:53:in `block in convert_to_html'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:52:in `each'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:52:in `convert_to_html'
    from /Users/tralfamadore/Sources/fdoc/lib/fdoc/cli.rb:41:in `convert'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
    from /Library/Ruby/Gems/2.0.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from fdoc/bin/fdoc:9:in `<main>'

JSON request params not properly parsed.

Using request specs I'm sending a Content-Type json and encoding the params hash as json before sending the request.

The problem is that fdoc sees the request params as just a string and doesn't look at each property, and gives me the following in the scaffolded fdoc:

requestParameters:
  type: string
  example: !binary |-
    eyJ2YWx1ZSI6NTQuMzYsImlkIjoiQjFsbjJ6OUpIWERZOG5XNyJ9

To fix this I am json parsing the params before they are sent to consume_request. This makes sense for us as all requests will be json anyway. Does anyone have any thoughts on how to do this in a more generic way? Perhaps it would help to have access to the content type header when consuming requests?

Error in path to endpoint

In https://github.com/square/fdoc/blob/master/docs/scaffold.md

require 'fdoc/spec_watcher'

describe MembersController do
include Fdoc::SpecWatcher

context "#list", :fdoc => 'members/filter' do
get :list, {
:limit => 10,
:older_than => Time.gm(2012,"jun",21,10,40,00)
}
end
end

:fdoc => 'members/filter' should be replaced by :fdoc => 'members/list' for correct end point as per the given example. Please suggest if I am correct or missed something obvious.

Custom Fdoc.service_path is broken in scaffold mode

In Fdoc::Service a DefaultService is created:

DefaultService = self.new(Fdoc::DEFAULT_SERVICE_PATH)

This uses the constant DEFAULT_SERVICE_PATH which has nothing to do with the Fdoc.service_path setting. This is normally not a problem, but as soon as we try to test with scaffold mode on (FDOC_SCAFFOLD=true) and the Fdoc.service_path is different from the default, an exception is being thrown:

No such file or directory - docs/fdoc
fdoc-0.2.3/lib/fdoc/service.rb:20:in `mkdir'
fdoc-0.2.3/lib/fdoc/service.rb:20:in `initialize'
fdoc-0.2.3/lib/fdoc/service.rb:30:in `new'
fdoc-0.2.3/lib/fdoc/service.rb:30:in `<class:Service>'
fdoc-0.2.3/lib/fdoc/service.rb:4:in `<top (required)>'
fdoc-0.2.3/lib/fdoc.rb:37:in `require'
fdoc-0.2.3/lib/fdoc.rb:37:in `<top (required)>'

By just removing the DefaultService things start to work again, so my question is: is the DefaultService really needed? It seems to be quite difficult to get a configuration for Fdoc.service_path in there before the DefaultService is created.

Mention render_views in readme

I am new to fdoc, and yesterday I spent whole night to make my fdoc pass the test. And I found that it failed because I didn't add render_views method in my controller test. So I think it would be better if we can add this method in readme.

What does it mean when decide_success is undefined?

 1) Sinatra::Application#channel create should respond to channel/create
     Failure/Error: post '/channel/create', body, h
     NoMethodError:
       undefined method `decide_success' for Fdoc:Module

My test looks like this:

  context "#channel create", :fdoc => "channel/create" do
    account = FactoryGirl.create(:account)
    it "should respond to channel/create" do
      h = {'Content-Type' => 'application/json'}
      body = { :api_key => account.secret }.to_json
      post '/channel/create', body, h
    end
  end

documenting request specs

Just looking into using this at @Jux... haven't delved into the source, but am I understanding the documentation correctly in that fdoc only works with controller specs? Is there a reason request specs aren't included? I write a lot more request specs than controller ones, as they also test the routing, which is particularly relevant for APIs.

--url-base-path option passed to fdoc convert is ignored from convertes

This seems due to the fact that on service.rb, the method used by view is done this way:

def base_path
  base_path = @schema['basePath']
  if base_path && !base_path.end_with?('/')
    base_path + '/'
  else
    base_path
  end
end

and @schema['basePath'] does not get overridden by option passed to fdoc convert Cli command.

Support for PATCH verb?

Is it possible to use PATCH with Fdoc? It does not seem to be included in the list of verbs for the spec watcher.

Environment variable interpolation

To get the right documentation published on different deploy contexts (i.e. both on staging environment and production environment) it would be very useful to be able to use environment variables inside fdoc.

In particular, it would be nice to be able to write something like this:

# my_service.fdoc.service
...
basePath: $env['CURRENT_ENV_BASE_PATH']/v1
...

So that when the documentation gets generated (deploy time), the right URL gets generated too into documentation.

Document how to manage versioned API

When a v1 version of an API exits, v0 should still be kept online and documented, but how do you manage this from a documentation point of view in your directory tree structure?

It would be very useful to have a real-world example of versioned API.

License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec,

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Even for projects that already specify a license, including a license in your gemspec is a good practice, since it is easily
discoverable there without having to check the readme or for a license file. For example, it is the field that rubygems.org uses to display a gem's license.

For example, there is a License Finder gem to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough
issue that even Bundler now generates gems with a default 'MIT' license.

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), github has created a license picker tool.

In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :).

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue and let me know. In either case, I'll follow up. Thanks!

p.s. I've written a blog post about this project

YAML inheritance

Is there any way to DRY up the fdoc response YAML files? I'd love to use something like YAML inheritance, but it doesn't seem to work.

I find myself constantly copy pasting YAMLs across PUT/POST/GET actions

it would be nice to somehow declare a base and have it shared across files

blogPostProperties: &blogPost
  title:
    description: the post title
    required: yes
    type: string
    example: Hello World Post!
  published:
    description: is it published?
    required: yes
    type: boolean
    example: false

Then, elsewhere in (another file) inherit the properties

# fdoc/blogPosts/:id-GET.fdoc
# ...
responseParameters:
  properties:
    blogPost:
      description: the post
      required: true
      type: object
      properties: *blogPost
        # include the base properties, then additionally include some others
        created_at:
          description: the date created
          required: true
          type: date
          example: 'TODAY'

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.