Fetching data asynchronously

Fetching data

The Runtime API supports fetch which provides an interface for asynchronously fetching resources via HTTP requests inside of a Worker.

Python example

The examples which follows show how a Worker interacts with the Hacker News API, then return HTML content.

handleRequest

URL = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty"
STORY = "https://hacker-news.firebaseio.com/v0/item/{}.json?print=pretty"

async def handleRequest(request):
    response = await fetch(URL)

    storyItems = await gatherResponse(response)

    storyBody = await getStoryBody(storyItems)

    htmlBody = await generateHTML(storyBody)


    return __new__(Response(htmlBody,{
        'headers' : { 'Content-Type' : 'text/html;charset=UTF-8' }
    }))

getStoryBody

This function makes a request for the story data (score, title)

async def getStoryBody(storyItems):
    storyBodyItems=[]
    for item in storyItems:
        storyBody = await fetch(STORY.format(item))
        storyBody.headers['Content-Type'] = 'application/json;charset=UTF-8'

        storyBodyResponse = await gatherResponse(storyBody)

        storyBodyItems.append(storyBodyResponse)        
    
    return storyBodyItems

gatherResponse

This function filters the response based on the content type.

async def gatherResponse(response):
    headers = response['headers']
    contentType = headers['Content-Type']
    
    if ("application/json" in contentType):
        return await response.json()
    else:
        return await response.text()

generateHTML

async def generateHTML(storyItems):
    html = """
        <!DOCTYPE html>
        <html>
            <head>
                <title>Cloudflare Workers: HN Top Stories Example </title>
                <!-- Bootstrap CSS -->
                <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
                    integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

            </head>
            <body>
                <div class="container" style="padding: 10px;">
                    <div class="row">
                        <div class="col-sm" style="width: 40rem;">
                            <div class="card">
                                
                                    {}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </body>
        </html>
    """
    storyItem = ""
    for item in storyItems:
        storyItem += "<div class='card-header'> <a href={} target='_blank'".format(item['url']) + ">" + item['title'] + "</a>" + " " + "[{}]".format(str(item['score'])) + "</div>"
        
    
    html = html.format(storyItem)

    return html

Preview

A HTML page showing a list of HN Stories with associated score, each story item has a corresponding URL.

Last updated on 13 Oct 2020
Published on 13 Oct 2020