상세 컨텐츠

본문 제목

URL Tree <Path Tree> - 생성

Language/..1

by yiaw 2021. 11. 5. 10:08

본문

Golang을 기반으로 RESTAPI를 설계하면서 권한관리 부분에 필요한 자료구조를 찾다 찾다 결국 .. 만들기로 했다.

얼추 기반을 만들어놓고 생각해 봤는데 .. Path Tree 쓰느니 .. Prefix Tree 쓰는게 좋았을수도 ... 그래도 일단 만들어 논거에 대해서 설명하자면 

 

각 Api + Method 별 권한을 관리하기 위해서는 Tree 구조를 사용하기로 했다. 

 

아래 URL Method가 있다고 할 경우 트리는 아래처럼 생성 된다.

GET       /api/v1/user

DELETE   /api/v1/user

GET       /api/v1/user/:name

POST     /api/v1/user/:name

DELETE   /api/v1/user/:name

GET       /api/v1/rules

DELETE   /api/v1/rules

GET       /api/v1/rules/:name

POST     /api/v1/rules/:name

DELETE   /api/v1/rules/:name

 

 

 

 

먼저 Node를 나타내는 구조체와 Tree 구조체이며, Tree 를 저장할 treeArray를 선언해 준다.

var treeArray map[string]*Tree

type Node struct {
	Path  string
	Child []Node
}

type Tree struct {
	Name string
	root []Node
}

 

트리 구조체 생성자 이다.

func NewTree(name string) *Tree {
	tree := &Tree{
		Name: name,
	}

	if len(treeArray) == 0 {
		treeArray = make(map[string]*Tree)
	}
	treeArray[name] = tree
	return tree
}

 

트리를 만드는 함수이다.

Path가 존재 하지 않으면 하위 Node에 추가하는 구조이다.  

맨처음 Method로 입력 받을 시에는 path , method 로 받고 내부적으로 재귀 호출 함수에서는 "/" 구분자로 각 string 배열에 담아 넘겨준다.

func (t *Tree) Make(method, path string) {

	if path == "" || method == "" {
		return
	}

	// path : /path/path => path/path
	b := []byte(path)
	if b[0] == '/' {
		b = b[1:]
		path = string(b)
	}

	// POST path/path => path/path/POST
	newPath := path + "/" + strings.ToUpper(method)

	p := strings.Split(newPath, "/")

	t.root = tmake(t.root, p)

}

func tmake(node []Node, p []string) []Node {
	var i int
	for i = 0; i < len(node); i++ {
		if node[i].Path == p[0] {
			break
		}
	}
	if i == len(node) {
		node = append(node, Node{Path: p[0]})
	}

	if len(p) != 1 {
		node[i].Child = tmake(node[i].Child, p[1:])
	}
	return node
}

 

Sample 코드로 해당 기능을 테스트 해보자 

package main

import (
	"urltree"
)

func main() {
	tree := urltree.NewTree("Sample")
	tree.Make("GET", "/api/v1/user")
	tree.Make("DELETE", "/api/v1/user")
	tree.Make("GET", "/api/v1/user/:name")
	tree.Make("POST", "/api/v1/user/:name")
	tree.Make("DELETE", "/api/v1/user/:name")
	tree.Make("GET", "/api/v1/rules")
	tree.Make("DELETE", "/api/v1/rules")
	tree.Make("GET", "/api/v1/rules/:name")
	tree.Make("POST", "/api/v1/rules/:name")
	tree.Make("DELETE", "/api/v1/rules/:name")

	tree.Printing()
 }
 ==== 출력 결과 ====
Sample
api
└── v1
   ├── user
      ├── GET
      ├── DELETE
      └── :name
         ├── GET
         ├── POST
         └── DELETE
   └── rules
      ├── GET
      ├── DELETE
      └── :name
         ├── GET
         ├── POST
         └── DELETE

 

이제 URL Method 매칭 방법에 대해서는 다음 포스팅에서 .. 

 

해당 소스 코드는 아래 Github 페이지에서 확인 할 수 있다.

github.com/yiaw/urltree

'Language > ..1' 카테고리의 다른 글

URL Tree <Path Tree> - 매칭  (0) 2021.11.05
Golang을 이용하여 Http Client - 세븐나이츠2 쿠폰 입력  (0) 2021.11.04

관련글 더보기

댓글 영역