2012-02-05 53 views
5

Tôi muốn hiển thị API REST trên ứng dụng của mình, sử dụng máy chủ web Mongoose và cung cấp trình xử lý cho các truy vấn khác nhau.Truy vấn REST phân tích cú pháp trong C++

Một ví dụ về truy vấn sẽ là như thế này (tôi chỉ sử dụng GET cho thời điểm này, phần còn lại của động từ HTTP sẽ đến sau):

GET /items -> returns a list of all items in JSON 
GET /item/by/handle/123456789 -> returns item that has handle 123456789 
GET /item/by/name/My%20Item -> returns item(s) that have the name "My Item" 

gì tôi tò mò là làm thế nào tôi nên thực hiện phân tích các truy vấn này. Tôi có thể dễ dàng phân tích cú pháp đầu tiên, vì nó chỉ đơn giản là một vấn đề của if(query.getURI() == "/items") return ....
Nhưng đối với hai truy vấn tiếp theo, tôi phải thao tác các chuỗi std:: theo một cách hoàn toàn khác, sử dụng một số phép thuật và bù trừ std::string::find() để nhận được đối số.

Như một ví dụ, đây là việc thực hiện Tôi có cho truy vấn thứ hai:

size_t position = std::string::npos; 
std::string path = "/item/by/handle/"; 

if((position = query.getURI().find(path)) != std::string::npos) 
{ 
    std::string argument = query.getURI().substr(position + path.size()); 
    // now parse the argument to an integer, find the item and return it 
} 

gì nếu tôi muốn "templatize" này; nghĩa là: Tôi mô tả đường dẫn và các đối số mà tôi mong đợi sau đó (một số nguyên, một chuỗi, ....); và mã được tạo tự động để xử lý việc này?

Tl; TS: Tôi muốn để có thể xử lý các truy vấn REST trong C++ với một cái gì đó dọc theo những dòng:

registerHandler("/item/by/handle/[INTEGER]", myHandlerMethod(int)); 

Đây có phải là có thể?

+0

Có vẻ như bạn cần cụm từ thông dụng, như được tìm thấy trong tăng hoặc C++ 11. –

Trả lời

4

Cách tiếp cận khá đơn giản nhưng đơn giản sẽ chỉ đơn giản là sử dụng sscanf. Tha thứ mã giống như C. Lưu ý, điều này không cung cấp loại cú pháp bạn đang tìm kiếm, nhưng nó không yêu cầu bất kỳ thư viện, tiện ích mở rộng hoặc tăng nào.

Ví dụ,

 
int param; 
int a, b; 
char c[255]; 

/* recall that sscanf returns the number of variables filled */ 
if(1 == sscanf(query.getURI(), "/item/by/handle/%d", &param)) { 

    handler(param); 

} else if (3 == sscanf(query.getURI(), "/more/params/%d/%d/%s", &a, &b, &c)) { 

    anotherHandler(a, b, c); 

} else { 
    // 404 
} 
+2

Lưu ý rằng việc sử dụng% s là nguy hiểm cho đầu vào của người dùng, vì nó không kiểm tra ranh giới và có thể dễ dàng bị tràn. Tôi đề xuất ví dụ trên: 'sscanf (query.getURI(),"/more/params /% d /% d /% 254s ", & a, & b, c)' – valenok

+0

Điểm tốt. Đối với những người muốn ngăn chặn điều này, Kernighan và Pike có một giải pháp dễ dàng: http://stackoverflow.com/questions/1621394/how-to-prevent-scanf-causing-a-buffer-overflow-in-c – Tom

1

Trong khi tìm kiếm thức ăn thông qua một số mã Python, tôi thấy rằng khuôn khổ Flask web có particular way of parsing REST paths:

Bạn khai báo một con đường như thế này:

@app.route('/post/<int:post_id>') 
def show_post(post_id): 
    # show the post with the given id, the id is an integer 
    return 'Post %d' % post_id 

Và Flask xây dựng những thứ cần thiết xung quanh để cung cấp cho bạn số nguyên bạn cần.

Đó chính xác là những gì tôi cần, vì vậy tôi đoán tôi sẽ phải tự mình làm trong C++.
Tôi sẽ nhận được câu trả lời của Tom vì câu trả lời có liên quan và tôi đoán triển khai của tôi sẽ trông giống như gợi ý (tôi có xu hướng thích iostream) hơn.

Tôi sẽ để lại câu trả lời này ở đây cho bất kỳ ai ẩn nấp xung quanh.

+0

http: //expressjs.com/ cũng có một tính năng tương tự. – Tom

+0

Bạn đã thực hiện cú pháp này trong C++ chưa? - Nếu vậy, bạn đã xem xét việc tìm nguồn cung ứng chưa? :) – stackoverflowuser95

+0

Than ôi, không.Tôi đã thay đổi công việc của mình và tìm thấy một số vấn đề khác để giải quyết .. – Gui13

Các vấn đề liên quan