How can I serve static files like swagger ui in Cloud functions - go

How can I serve swagger-ui-dist in Cloud Function with Go?
Out of Cloud Functions environment I would do:
package main
import (
"fmt"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("./swagger-ui-dist"))
http.Handle("/swaggerui/", http.StripPrefix("/swaggerui/", fs))
http.ListenAndServe(":8080", nil)
}
But since Cloud functions use a normal function as handler using the Standard http.HanlderFunc interface I don't know how to make it work.
I have tried to simulate this scenario to do my tests with http.ServeFile, but didn't work. Seems like is not downloading all the contents of the folder.
package main
import (
"fmt"
"net/http"
)
func cloudFunctionHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./swagger-ui-dist")
}
func main() {
http.HanldeFunc("/swaggerui/", handler)
http.ListenAndServe(":8080", nil)
}

I tried it in several way and it worked locally with the same behavior as Cloud Function (same function signature), but it didn't work after deployment on Cloud Functions.
I understood why. In fact Buildpack (the tools develped by Google for building a container without a Dockerfile, and now in the CNCF sandbox) compiles the .go file and copy the binary to the final container layer. All the other files/directory are omitted. Thus, it can't work!
I recommend you to use Cloud Run (same underlying platform as Cloud Functions, and in some cases, cheaper. I wrote an article on this)
The other solution is to use a not compiled language such as NodeJS or Python.

It is actually possible in three ways (that I know):
Serve the static files from a CDN. E.g. from http://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.40.0/
Host the static files yourself on a different endpoint
Add the static files to the root folder of your cloud function. These will be packaged together with your code and therefore be available when deployed
(I went for option 3)
For options 2 and 3 you have to override the folder that swaggerui uses for its static assets. How you do this depends on how you configure the swagger ui.
In my case I was using the flask_restx Python package to generate the swagger.json and serve the swaggerui. So I monkeypatched like so:
from flask_restx.apidoc import apidoc
apidoc.static_folder = '<MY STATIC FOLDER PATH' # e.g. os.path.abspath('static/swaggerui')
Also, you need to copy the files from the swaggerui library to your function's root directory before running gcloud function deploy ....
I copy the static folder from flask_restx to my function's root directory during my CI pipeline.
Hope this helps anyone!

Related

Questions about golang importing jwt

package common
import (
"github.com/dgrijalva/jwt-go"
)
type Claims struct {
UserId uint
jwt.StandardClaims
}
Above is my code. Today, after using the gin and gorm framework normally, I created a new jwt.go file in the common package. When I run the main function, golang prompts an error (undefined: jwt) in the last line, but in the go.mod file, I am prompted that I have downloaded "github. com/dgrijalva/jwt-go".
I tried to get github.com/dgrijalva/jwt-go and import go get - u github.com/golang-jwt/jwt again, but neither of the two methods worked

How to correctly import an aws-sdk-go service?

I am fairly new to the Go programming language and completely new to the Go SDK from AWS. I am trying to use a service but I have a strange problem where the types defined by the imported service are found, but the functions of the service are undefined.
This question is not about using the particular service, but just how to correctly import it. My code:
package auth
import (
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
)
func SignUpTest() {
input := cognitoidentityprovider.SignUpInput{
Username: aws.String("example#mail.com"),
Password: aws.String("test1234"),
}
_, err := cognitoidentityprovider.SignUp(&input)
if err != nil {
log.Fatal(err)
}
}
I get the following error when running go build:
auth/signup.go:18:12: undefined: cognitoidentityprovider.SignUp
The autocomplete in my IDE also states that it can find the cognitoidentityprovider.SingUpInput struct, but it is unable to find the cognitoidentityprovider.SignUp function.
I use Go 1.10.1 on WSL Ubuntu. I use DEP 0.4.1 for package management. I verified that the AWS SDK is available in the vendor folder and that the cognitoidentityprovider package is available (the SignUp) function is also there.
What am I missing here?
The error says it all. cognitoidentityprovider.SignUp isn't defined, because there is no symbol SignUp exported by the cognitoidentityprovider package.
I'm not really sure what you want to do instead, since I'm not familiar with that SDK, but you're trying to call a function that doesn't exist. I suggest re-examining the documentation or example you're following. You've probably made a simple mistake.
You seem to be confused by the CognitoIdentityProvider.SignUp instance method. But as that's an instance method, and not an exported function, it requires an instance of a CognitoIdentityProvider first:
cip := cognitoidentityprovider.New( ... )
_, err := cip.SignUp(input)

golang mobile access file system

How can i access the device system in gomobile?
Is there a way to interact with the native libs?
Like this:
package xy
import(
"Foundation"// ios libraray
)
// Do some stuff with the Foundation package
func Test(){
}
Yes. Take a look at Reverse Bindings here; https://godoc.org/golang.org/x/mobile/cmd/gobind
To summarise, you import the Android/ObjectiveC library and are good to go.
The example they give;
import "ObjC/Foundation/NSDate
d := NSDate.Date()

How to make a new Perfect Project from scratch (Swift server) in xcode?

Perfect is a new Swift Framework for creating a web/http server in swift. The documentation is not there yet and I find trouble with building a new project from scratch. I don't know which frameworks are necessary to import and which one is the entry point of the app. main.swift etc...
I'd like to make a new xcworkspace that will have my project, "a hello world server".
Problems I'm trying to tackle:
Which frameworks must be included?
How should I create a Perfect server, what's the entry point of the app?
How to create a "hello" root which responds with a "Hello World message"?
How should I make the target for the server and eventually run the server?
I managed to write a "Hello World" guide about this. http://code-me-dirty.blogspot.co.uk/2016/02/creating-perfect-swift-server.html
In a nutshell you need to proceed like this:
clone the original project
Create a new Workspace
Create a new Project
Import PerfectLib.xcodeproject & Import PerfectServer.xcodeproject but do not copy
Setup your project scheme to launch the PerfectServer HTTP App
Link the PerfectLib onn the "Linked Frameworks and Libraries" section
setup Build settings for your framework target*
Create PerfectHandlers.swift and paste(better write to get the feeling) the following code
import PerfectLib
//public method that is being called by the server framework to initialise your module.
public func PerfectServerModuleInit() {
// Install the built-in routing handler.
// Using this system is optional and you could install your own system if desired.
Routing.Handler.registerGlobally()
// Create Routes
Routing.Routes["GET", ["/", "index.html"] ] = { (_:WebResponse) in return IndexHandler() }
// Check the console to see the logical structure of what was installed.
print("\(Routing.Routes.description)")
}
//Create a handler for index Route
class IndexHandler: RequestHandler {
func handleRequest(request: WebRequest, response: WebResponse) {
response.appendBodyString("Hello World")
response.requestCompletedCallback()
}
}
Then you are ready to run. On my blog I have a long, more detailed version of this and I will update here if necessary.
Build Settings
Deployment Location: Yes
Installation Build Products Location : $(CONFIGURATION_BUILD_DIR)
Installation Directory : /PerfectLibraries
Skip Install : NO
I just wrote up a tutorial I want to share as another solution that outlines how to create a web service with Perfect and an app to interact with it.
http://chrismanahan.com/creating-a-web-service-swift-perfect
Summary
You must have your project in a workspace. This workspace should also include the PerfectServer and PerfectLib projects.
In your project, create a new OSX Framework target. This will be your server target
Link PerfectLib with both your server target and your app's target (if you're building an app alongside the server)
Edit your server's Run scheme to launch with PerfectServer HTTP App.
In your Server target's Build Settings, set the following flags:
Skip Install = No
Deployment Location = Yes
Installation Directory = /PerfectLibraries
Installation Build Products Location = $(CONFIGURATION_BUILD_DIR)
Create a new file in the server's folder. This file will handle requests that come in. Include [most of] the following:
import PerfectLib
// This function is required. The Perfect framework expects to find this function
// to do initialization
public func PerfectServerModuleInit() {
// Install the built-in routing handler.
// This is required by Perfect to initialize everything
Routing.Handler.registerGlobally()
// These two routes are specific to the tutorial in the link above.
// This is where you would register your own endpoints.
// Take a look at the docs for the Routes API to better understand
// everything you can do here
// register a route for gettings posts
Routing.Routes["GET", "/posts"] = { _ in
return GetPostHandler()
}
// register a route for creating a new post
Routing.Routes["POST", "/posts"] = { _ in
return PostHandler()
}
}
class GetPostHandler: RequestHandler {
func handleRequest(request: WebRequest, response: WebResponse) {
response.appendBodyString("get posts")
response.requestCompletedCallback()
}
}
class PostHandler: RequestHandler {
func handleRequest(request: WebRequest, response: WebResponse) {
response.appendBodyString("creating post")
response.requestCompletedCallback()
}
}
As you're building out different aspects of your service, you can test it by using cURL in the command line, or other REST testing tools like Postman
If you wanna dive deeper and learn how to integrate with a SQLite database or create an app that talks with your new server, check out the tutorial at the top of this post.
I would recommend staying away from the templates, as others suggested, and create a clean project yourself.
Create this folder structure:
MyAPI
├── Package.swift
└── Sources
└── main.swift
Then, in the Package.swift file
import PackageDescription
let package = Package(
name: "MyAPI",
targets: [],
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2)
]
)
And the main.swift file:
import PerfectHTTP
import PerfectHTTPServer
do {
let route = Route(method: .get, uri: "/hello", handler: { (request: HTTPRequest, response: HTTPResponse) in
response.appendBody(string: "world!")
response.completed()
})
try HTTPServer.launch(.server(name: "localhost", port: 8080, routes: [route]))
} catch {
fatalError("\(error)")
}
Go to the command line and run:
swift package generate-xcodeproj
Open the generated project file:
MyAPI.xcodeproj
Change the active scheme, then build and run:
Open in safari:
http://localhost:8080/hello
I'm not sure if you have found a solution or not, but this is what I did:
The 'Tap Tracker' app is an app written the the Perfect libraries, so even if documentation isn't ready yet you can still dissect the app. I renamed the app, and the classes/methods. There's a single index.html, which I moved into a 'www' root, and then rerouted the view with TTHandler to try and make a standard layout. It doesn't work very well because the framework is so young, but it can be done. I would be much more specific but I went back to rails for the time being because I want to wait until it's a little more mature.
It's fun to mess around with, and I will probably write my own library on top of perfect onc feature innovation calms down and I can make something stable with it.
Just copy all files from one of the sample-projects to your git repository:
https://github.com/PerfectExamples
Rename the example_project_name in all files (you've copied) to your project name.
In terminal run
swift package generate-xcodeproj
And you'll get a Perfect Project with the required name.

First go program doesn't display index page

I followed creating a basic web app with go, I created the folder with name myApp. In myApp have main.go and public folder(in public have index.html), here is my content in main.go:
package main
import "net/http"
import "github.com/russross/blackfriday"
func main() {
http.HandleFunc("/markdown", GenerateMarkdown)
http.Handle("/", http.FileServer(http.Dir("public")))
http.ListenAndServe(":8080", nil)
}
func GenerateMarkdown(rw http.ResponseWriter, r *http.Request) {
markdown := blackfriday.MarkdownCommon([]byte(r.FormValue("body")))
rw.Write(markdown)
}
I started server and go to http://localhost:8080/ but it doesn't link to index.html. Can anyone explain why it doesn't render index.html file. I'm a newbie in Golang.
This was answered in the comments, so here is a summary for completeness or something.
The code presented in the question produced the expected results after the actual build->run->test->repeat process was clarified for OP. Points of clarification were as follows:
After using go build to compile the binary, the program isn't running yet. Be sure to actually execute the binary before trying to connect to the server.
If it's necessary to make changes, stop the server, run go build again, then run the new binary.
As a side note, gin is a tool that tries to automate this process by rebuilding and launching your program each time you save the file.

Resources