zoukankan      html  css  js  c++  java
  • Simple Web API Server in Golang (1)

    To be an better Gopher, get your hands dirty. Topcoder offered a serials of challenges for learning Golang.

    In this blog, I tried to implement "Go Learning Challenge - Simple Web-API Server"[1].

    What's used in this challenge ? Following aspects and packages will be covered in this challenge

    • How to create a HTTP server: net/http
    • How to create routers (handlers for different URLs): regex + url
    • How to write HTTP responses: net/http
    • How to load JSON config: json + io/ioutil
    • How to parse URL query string: url
    • How to encode data in sha256/base64: sha256/base64  + strings
    • How to write tests in Golang: testing
    • How to parse command line arguments: flag
    • How to log: log

    Configuration File example:

    [
        {
            "domain": "topcoder.com",
            "users": [
                {
                    "username": "takumi",
                    "password": "ilovego"
                },
                {
                    "username": "teru",
                    "password": "ilovejava"
                },
                {
                    "username": "toshi",
                    "password": "iloveapex"
                }
            ]
        },
        {
            "domain": "appirio.com",
            "users": [
                {
                    "username": "jun",
                    "password": "ilovetopcoder"
                },
                {
                    "username": "narinder",
                    "password": "ilovesamurai"
                },
                {
                    "username": "chris",
                    "password": "ilovesushi"
                }
            ]
        }
    ]

    config.go

    package SimpleWebAPIServer
    
    import (
        "io/ioutil"
        "encoding/json"
        "errors"
    )
    
    type User struct {
        UserName string `json:"username"`
        Password string `json:"password"`
    }
    
    type Domain struct {
        Name string `json:"domain"`
        Users UserList `json:"users"`
    }
    
    type DomainWarehouse []Domain
    type UserList []User
    
    func ReadConfig(fn string) (DomainWarehouse, error) {
        data, err := ioutil.ReadFile(fn)
        if err != nil {
            return nil, err
        }
        //fmt.Println(string(data))
    
        var m DomainWarehouse
        json.Unmarshal(data, &m)
        return m, nil
    }
    
    
    func (dw DomainWarehouse) GetDomain(name string) (*Domain, error) {
        for _, domain := range dw {
            if domain.Name == name {
                return &domain, nil
            }
        }
        return nil, errors.New("Failed to find domain")
    }
    
    func (ul UserList) GetUser(username string) (*User, error) {
        for _, user := range ul {
            if user.UserName == username {
                return &user, nil
            }
        }
        return nil, errors.New("Failed to find user")
    }

    tests for config.go

    package SimpleWebAPIServer
    
    import (
        "testing"
        "fmt"
    )
    
    func TestReadConfig(t *testing.T) {
        dw, err := ReadConfig("./users.json")
        if err != nil {
            fmt.Println(err)
            t.Error("Failed to read config")
        }
        if dw == nil || len(dw) != 2 {
            t.Error("Failed to unmarshal json objects")
        }
    
        if dw[0].Name != "topcoder.com" || len(dw[0].Users) != 3 {
            t.Error("Incorrect value")
        }
    }
    
    func TestGetDomain(t *testing.T) {
        dw, err := ReadConfig("./users.json")
        if err != nil {
            fmt.Println(err)
            t.Error("Failed to read config")
        }
        domain, err := dw.GetDomain("topcoder.com")
        if err != nil {
            fmt.Println(err)
            t.Error("Failed to get domain")
        }
        if domain.Name != "topcoder.com" || len(domain.Users) != 3 {
            t.Error("Incorrect value")
        }
    }
    
    func TestGetUser(t *testing.T) {
        dw, err := ReadConfig("./users.json")
        if err != nil {
            fmt.Println(err)
            t.Error("Failed to read config")
        }
        domain, err := dw.GetDomain("topcoder.com")
        if err != nil {
            fmt.Println(err)
            t.Error("Failed to get domain")
        }
        if domain.Name != "topcoder.com" || len(domain.Users) != 3 {
            t.Error("Incorrect value")
        }
    
        ul := domain.Users
        u, err := ul.GetUser("takumi")
        if err != nil {
            t.Error("Failed to get user")
        }
        if u.UserName != "takumi" || u.Password != "ilovego" {
            t.Error("Invalid user values")
        }
    }

    After implementing this simple web api server, I got better understanding of Golang syntax and Web API stuffs. For more Web API server challenges, go to [3] about OAuth2.

    [1] topcoder : http://www.topcoder.com/challenge-details/30046011/?type=develop&noncache=true

    [2] git : https://coding.net/u/huys03/p/SimpleWebAPIServer/git

    [3] next challenge: http://www.topcoder.com/challenge-details/30046224/?type=develop

  • 相关阅读:
    CSS简单的四种引入方式
    html之表单标签
    html基础标签之head和body标签
    Python之协程的实现
    Python之实现不同版本线程池
    Python多进程之multiprocessing模块和进程池的实现
    Python之queue模块
    sqlserver 时间格式化
    关于sql server 代理(已禁用代理xp)解决办法
    sqlserver如何启动数据库邮件
  • 原文地址:https://www.cnblogs.com/huys03/p/4051264.html
Copyright © 2011-2022 走看看