Skip to content

Commit

Permalink
adding doc examples into project
Browse files Browse the repository at this point in the history
  • Loading branch information
David Boyne authored and David Boyne committed Jul 29, 2024
1 parent 2b18e76 commit 9e27b73
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 0 deletions.
147 changes: 147 additions & 0 deletions docs/examples/basic-auth-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
title: "API using basic authentication"
subtitle: "Example application that exposes an API behind basic authentication"
type:
- "pattern"
platform:
- "awscdk"
- "tf-aws"
- "sim"
language:
- "wing"
githubURL: "https://github.com/winglang/examples.git && cd examples/examples/api-basic-auth"
coverImage: "/img/examples/basic-api-auth.png"
coverImageInPage: true
resources:
- label: "Understand preflight and inflight concepts"
href: "/docs/concepts/inflights"
- label: "Explore the Wing api resource"
href: "/docs/api/standard-library/cloud/api"
authors:
- name: "David Boyne"
role: "Developer Advocate, Wing"
twitter: "https://twitter.com/boyney123"
github: "https://github.com/boyney123"
cloudResources:
- api
---

This example application deploys an [API](/docs/api/standard-library/cloud/api) with a GET route called `/user`. The route is behind basic authentication and returns a 401 if un-authorized.

In this example a custom **BasicAuth** class is created. This class exposes a public inflight method (called verify) that is used within the API to verify the request.

> **Did you know resources have a preflight and inflight API?** [Preflight](/docs/concepts/inflights) code runs once, at compile time whereas [inflight](/docs/concepts/inflights) code is run at runtime. In this example we create the BasicAuth and API resources on preflight (default for Wing files) and then use the BasicAuth method (verify) in the API itself (on inflight). To learn more you can read [preflight and inflight](/docs/concepts/inflights#preflight-code) core concepts.

```js example playground
bring cloud;
bring util;
bring http;

struct Credentials {
username: str;
password: str;
}

// Custom class for the authentication logic
class BasicAuth {
user: str;
password: str;

new(user: str?, password: str?) {
// Default credentials
this.user = user ?? "admin";
this.password = password ?? "admin";

// Custom icon and color for the node
nodeof(this).icon = "lock-closed";
nodeof(this).color = "red";
}

// public function to verify the requests
pub inflight verify(req: cloud.ApiRequest): bool {
try {
let authHeader = this.authHeader(req.headers);
let credentials = this.authCredentials(authHeader);
let username = credentials.username;
let password = credentials.password;
return username == this.user && password == this.password;
} catch e {
log("exception caught {e}");
return false;
}
}

// Decodes the given header and returns username and password
inflight authCredentials(header: str): Credentials {
let auth = util.base64Decode(header.split(" ").at(1));
let splittedAuth = auth.split(":");
let username = splittedAuth.at(0);
let password = splittedAuth.at(1);

return Credentials {
username: username,
password: password
};
}
// Returns the authorization header
inflight authHeader(headers: Map<str>?): str {
if (this.authHeaderPresent(headers)) {
let authHeaderOptional = headers?.tryGet("authorization");
let var authHeader = headers?.tryGet("Authorization");

if (authHeader == nil) {
authHeader = authHeaderOptional;
}

return authHeader!;
} else {
log("headers: {Json.stringify(headers)}");
log("no auth header");
throw("no auth header");
}
}

inflight authHeaderPresent(headers: Map<str>?): bool {
if (headers?.has("authorization") == false) && (headers?.has("Authorization") == false) {
return false;
}
return true;
}

}

// Create a new instance of the BasicAuth class
let auth = new BasicAuth() as "Basic auth verification";

// Create a new API
let api = new cloud.Api() as "Users API";

// Create the route /user and protect with basic auth
api.get("/user", inflight (req) => {
let authenticated = auth.verify(req);

if (!authenticated) {
return {
status: 401,
headers: {
"Content-Type" => "text/plain"
},
body: "Unauthorized"
};
}

return {
status: 200,
headers: {
"Content-Type" => "text/plain"
},
body: Json.stringify({ "firstname": "David", "lastname": "Boyne" })
};
});
```
### Resources used in this example
- [Api](/docs/api/standard-library/cloud/api) - Resource for cloud api
81 changes: 81 additions & 0 deletions docs/examples/deploy-a-static-website.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: "Deploy a static website with Wing"
subtitle: "Example application that deploys a static website into the cloud"
type:
- "pattern"
platform:
- "awscdk"
- "tf-aws"
- "sim"
language:
- "wing"
githubURL: "https://github.com/winglang/examples.git && cd examples/examples/static-website"
coverImage: "/img/examples/static-website.png"
coverImageInPage: true
coverImageOptions:
awscdk: "/img/examples/static-website-aws.png"
"tf-aws": "/img/examples/static-website-aws.png"
resources:
- label: "Understanding inflight and preflight"
href: "/docs/concepts/inflights"
- label: "Explore the Wing website cloud resource"
href: "/docs/api/standard-library/cloud/website"
- label: "Explore the Wing api cloud resource"
href: "/docs/api/standard-library/cloud/api"
authors:
- name: "David Boyne"
role: "Developer Advocate, Wing"
twitter: "https://twitter.com/boyney123"
github: "https://github.com/boyney123"
cloudResources:
- website
- api
- counter
---

This example application deploys a static website to the cloud using a [website](/docs/api/standard-library/cloud/website) resource. Additionally, it includes an [API resource](/docs/api/standard-library/cloud/api) featuring a `/hello-static` **POST** endpoint.

The deployed website shows a button which makes a POST request to the API to increment a counter value.

> The `/hello-static` POST endpoint in this example returns an [inflight function](/docs/concepts/inflights#inflight-code). This is runtime code. When a request is received at this endpoint, the inflight code is executed.
```js example playground
bring cloud;
bring util;
bring http;
bring expect;

let website = new cloud.Website(
path: "./static",
);

let api = new cloud.Api({
cors: true,
corsOptions: {
allowHeaders: ["*"],
allowMethods: [http.HttpMethod.POST],
},
});
website.addJson("config.json", { api: api.url });

let counter = new cloud.Counter() as "website-counter";

api.post("/hello-static", inflight (request) => {
return {
status: 200,
headers: {
"Content-Type" => "text/html",
"Access-Control-Allow-Origin" => "*",
},
body: "<div id=\"hello\" class=\"mt-4\">Hello {counter.inc()}</div>",
};
});

```

### Resources used in this example

- [Website](/docs/api/standard-library/cloud/website) - Deploy static websites into the cloud
- [API](/docs/api/standard-library/cloud/api) - Create APIs and deploy them into the cloud
- [Counter](/docs/api/standard-library/cloud/counter) - Stateful container for one or more numbers in the cloud

11 changes: 11 additions & 0 deletions docs/examples/introduction-to-preflight-and-inflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: "Introduction to preflight and inflight"
subtitle: "A hands on tutorial to teach preflight and inflight execution phases"
type:
- "interactive tutorial"
coverImage: "/img/examples/introduction-to-preflight-and-inflight.png"
url: https://www.winglang.io/learn/preflight-inflight
cloudResources:
- bucket
- function
---
12 changes: 12 additions & 0 deletions docs/examples/introduction-to-wing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "Introduction to Wing"
subtitle: "A step-by-step introductory guide to the Winglang cloud programming language"
type:
- "interactive tutorial"
coverImage: "/img/examples/introduction-to-wing.png"
url: https://www.winglang.io/learn
cloudResources:
- queue
- bucket
- function
---
64 changes: 64 additions & 0 deletions docs/examples/processing-messages-in-a-queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: "Processing messages in a queue"
subtitle: "Example application that processes messages form a queue and puts information into a bucket"
type:
- "pattern"
platform:
- "awscdk"
- "tf-aws"
- "sim"
language:
- "wing"
githubURL: "https://github.com/winglang/examples.git && cd examples/examples/hello-wing"
coverImage: "/img/examples/basic-bucket-queue.png"
coverImageInPage: true
resources:
- label: "Understanding inflight and preflight"
href: "/docs/concepts/inflights"
- label: "Explore the Wing queues"
href: "/docs/api/standard-library/cloud/queue"
- label: "Explore the Wing buckets"
href: "/docs/api/standard-library/cloud/bucket"
authors:
- name: "David Boyne"
role: "Developer Advocate, Wing"
twitter: "https://twitter.com/boyney123"
github: "https://github.com/boyney123"
cloudResources:
- queue
- bucket
---

This pattern creates a [bucket](/docs/api/standard-library/cloud/bucket) and a [queue](/docs/api/standard-library/cloud/queue). When messages are pushed the queue an [inflight function](/docs/concepts/inflights#inflight-code) processes the message and puts the contents of the message into a bucket.

> The [inflight function](/docs/concepts/inflights#inflight-code) is executed at runtime. During this execution, inflight code can interact with resources through their inflight APIs (e.g. [bucket inflight APIS](/docs/api/standard-library/cloud/bucket#inflight-methods)). In this example, information is added to the bucket by using the inflight [put API](/docs/api/standard-library/cloud/bucket#@winglang/sdk.cloud.IBucketClient.put) provided by the bucket.
```js example playground
bring cloud;
bring util;
bring expect;

let bucket = new cloud.Bucket();
let queue = new cloud.Queue();

queue.setConsumer(inflight (message) => {
bucket.put("wing.txt", "Hello, {message}");
}, timeout: 30s);

test "Hello, world!" {
queue.push("world!");

let found = util.waitUntil(() => {
log("Checking if wing.txt exists");
return bucket.exists("wing.txt");
});

expect.equal(bucket.get("wing.txt"), "Hello, world!");
}
```

### Resources used in this example

- [Queue](/docs/api/standard-library/cloud/queue) - Resource for holding lists of messages.
- [Bucket](/docs/api/standard-library/cloud/bucket) - Resource for storing data in the cloud.

51 changes: 51 additions & 0 deletions docs/examples/redis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "Using Redis with Wing"
subtitle: "Example application that uses Redis to set cache values from a queue"
type:
- "pattern"
platform:
- "awscdk"
- "sim"
language:
- "wing"
githubURL: "https://github.com/winglang/examples.git && cd examples/examples/redis"
coverImage: "/img/examples/redis.png"
coverImageInPage: true
resources:
- label: "Redis winglib"
href: "https://github.com/winglang/winglibs/tree/main/redis"
- label: "Explore Wing functions"
href: "/docs/api/standard-library/cloud/function"
authors:
- name: "David Boyne"
role: "Developer Advocate, Wing"
twitter: "https://twitter.com/boyney123"
github: "https://github.com/boyney123"
cloudResources:
- function
---

This basic pattern uses the [redis winglib](https://github.com/winglang/winglibs/tree/main/redis) with a [cloud function](/docs/api/standard-library/cloud/function).

When the cloud function is invoked a value is set in the redis database using the redis inflight API.


```js example
bring redis;
bring cloud;

// Create a reddit resource
let redisInstance = new redis.Redis();

new cloud.Function(inflight () => {
// Set value in the redis cache
redisInstance.set("mykey", "myvalue");
});
```


### Resources used in this example

- [Function](/docs/api/standard-library/cloud/function) - Resource for holding lists of messages.
- [Redis winglib](https://github.com/winglang/winglibs/tree/main/redis) - Resource for storing data in the cloud.

0 comments on commit 9e27b73

Please sign in to comment.