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

时间: 2024-08-27 09:41:50

Simple Web API Server in Golang (1)的相关文章

Simple Web API Server in Golang (2)

In this challenge, I tried to implement a simple OAuth2 server basing on Simple Web API Server in [1]. For OAuth2, go to http://oauth.net/2/. Endpoint /api/2/domains/{domain name}/oauth/access_token Use port 80. We would like to use other ports such

【翻译】在Visual Studio中使用Asp.Net Core MVC创建你的第一个Web API应用(一)

HTTP is not just for serving up web pages. It's also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can re

Introduction to ASP.NET Web API

Services for Native AppsAs stated earlier, smartphones had an important part in the trend toward simpler pure HTTP API and away fromSOAP. Many of the native apps can be likened to dumb terminals connected to a big mainframe, with the mainframebeing t

Hosting Web API in Windows service

Running your api as Windows services can have multiple advantages, especially when working on bigger projects. This allows for multiple (services to run in isolation and gives fine grained control over your system components. ASP.NET Web API ships wi

How to Check Whether API Server is up or Down

Introduction In this article we will create a small utility using C# that tells us whether our API server is up or down. Purpose Our purpose is to check the API server so, we can make a request for our resources. It is recommended that before making

Asp.Net MVC 4 Web API 中的安全认证-使用OAuth

Asp.Net MVC 4 Web API 中的安全认证-使用OAuth 各种语言实现的oauth认证: http://oauth.net/code/ 上一篇文章介绍了如何使用基本的http认证来实现asp.net web api的跨平台安全认证. 这里说明一个如何使用oauth实现的认证.oauth大家可能不陌生.那么这里需要注意的是我们使用的是.net平台一个比较好的开源oauth库. DOTNETOPENAUTH. 就像上图所示,我们需要一个ISSSUE Server来给我们一个token

使用Python的http.server实现一个简易的Web Api对外提供HanLP拼音转换服务

由于采集省市区镇数据需要对地名进行拼音转换,由于第三方高准确度接口对IP进行了限制,处理大量数据变得异常缓慢. 使用了一个折中的办法,省市区 3级(3千+)用高准确度接口(几乎没有拼错的地名),镇级(4万+)用本地HanLP提供的接口(大部分多音字还算是能拼正确). Github源码:https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov/tree/master/.pinyin-python-server 另外我提供了一个临时测试服务器,

A simple Test Client built on top of ASP.NET Web API Help Page

Step 1: Install the Test Client package Install the WebApiTestClient package from the NuGet Package Manager. Make sure to “Include Prerelease” then just type in “WebApiTestClient” and click Install. Once the package is installed, it will add the foll

JSON Web Token in ASP.NET Web API 2 using Owin

In the previous post Decouple OWIN Authorization Server from Resource Server we saw how we can separate the Authorization Server and the Resource Server by unifying the "decryptionKey" and "validationKey" key values in machineKey node