Closed mihirpmehta closed 4 years ago
Hi @mihirpmehta, I haven't tried to import Redis and Postgresql. I suggest to try to import the libraries you find here: https://swift.org/server/ The requirement to integrate a library is:
Thanks for your response. I tried to integrate https://github.com/IBM-Swift/Swift-Kuery with given example but getting runtime error
/var/task/HelloWorld: error while loading shared libraries: libpq.so.5: cannot open shared object file: No such file or directory
Here is my docker file
FROM swift:5.1.1 as builder
RUN apt-get -qq update && apt-get -q -y install \
libssl-dev libicu-dev
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libpq-dev
Will try to import libraries from https://swift.org/server/ and give it a try
Thanks
@mihirpmehta If you add a library to the code, you need to copy them or in the Layer or with the Lambda. Look at the structure of the Docker folder, there is a text file called swift-shared-library.txt that contains all the libraries you need to add to your layer. I suggest creating your version of that file with the library you need. Once you add the library don't forget to upload the layer on AWS.
Thank you for your guidance. I am able to run the lambda with third party library now. Just one more query that i cannot resolve is, Can i run/test it in my local machine on terminal ? I am using Visual Code and Mac
Thanks
It's possible to run the test by using make test_package
. But you need to add your unit test in swift. You should be able test the lambda. Look also to the packages to have some idea on how to do it.
You can run the test using visual studio code and the docker. The project has the configuration to support it. Look here on how to setup the environment: https://github.com/ianpartridge/vscode-remote-try-swift
Thanks. Will give it a try :)
Redis: Here an example on how to use Redis with Swift Sprinter
Package.swift
import PackageDescription
let package = Package(
name: "RedisDemo",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/swift-sprinter/aws-lambda-swift-sprinter-nio-plugin", from: "1.0.0-alpha.3"),
.package(url: "https://gitlab.com/mordil/swift-redi-stack.git", from: "1.0.0-alpha.5"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A starget can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "RedisDemo",
dependencies: ["LambdaSwiftSprinterNioPlugin", "Logging", "RediStack"]),
.testTarget(
name: "RedisDemoTests",
dependencies: ["RedisDemo"]),
]
)
Main.swift
import AsyncHTTPClient
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
import LambdaSwiftSprinter
import LambdaSwiftSprinterNioPlugin
import Logging
import NIO
import NIOFoundationCompat
import RediStack
struct Event: Codable {
let key: String
let value: String
}
struct Response: Codable {
let value: String
}
enum LambdaError: Error {
case redisConnectionFailed
}
let logger = Logger(label: "AWS.Lambda.Redis")
let elasticacheConfigEndpoint = "<your cluster>.euw1.cache.amazonaws.com"
let eventLoop = httpClient.eventLoopGroup.next()
let connection = try? RedisConnection.connect(
to: try .makeAddressResolvingHost(elasticacheConfigEndpoint,
port: RedisConnection.defaultPort),
on: eventLoop
).wait()
let syncCodableNIOLambda: SyncCodableNIOLambda<Event, Response> = { (event, context) throws -> EventLoopFuture<Response> in
guard let connection = connection else {
throw LambdaError.redisConnectionFailed
}
let future = connection.set(event.key, to: event.value)
.flatMap {
return connection.get(event.key)
}
.map { content -> Response in
return Response(value: content ?? "")
}
return future
}
do {
let sprinter = try SprinterNIO()
//Note amend this line in case if it's required to use a different lambda handler.
sprinter.register(handler: "setGet", lambda: syncCodableNIOLambda)
try sprinter.run()
} catch {
logger.error("\(String(describing: error))")
}
Note I used Redis with AWS Elastic Cache
Requirements:
The full example is here: https://github.com/Andrea-Scuderi/aws-lambda-swift-sprinter/tree/feature/Redis
Redis:
Here an example on how to use PostgreSQL with Swift Sprinter:
Package.swift
import PackageDescription
let package = Package(
name: "PostgreSQLDemo",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/swift-sprinter/aws-lambda-swift-sprinter-nio-plugin", from: "1.0.0-alpha.3"),
.package(url: "https://github.com/vapor/postgres-nio.git", from: "1.0.0-alpha.1.6"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "PostgreSQLDemo",
dependencies: ["LambdaSwiftSprinterNioPlugin", "Logging", "PostgresNIO"]),
.testTarget(
name: "PostgreSQLDemoTests",
dependencies: ["PostgreSQLDemo"]),
]
)
main.swift
import AsyncHTTPClient
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
import LambdaSwiftSprinter
import LambdaSwiftSprinterNioPlugin
import Logging
import NIO
import NIOFoundationCompat
import PostgresNIO
struct Event: Codable {
let query: String
}
struct Response: Codable {
let value: String
}
enum LambdaError: Error {
case connectionFailed
}
let logger = Logger(label: "AWS.Lambda.Redis")
let endpoint = "<yourdb>.rds.amazonaws.com"
do {
let eventLoop = httpClient.eventLoopGroup.next()
let connection = try PostgresConnection.connect(
to: try .makeAddressResolvingHost(endpoint,
port: 5432),
on: eventLoop
).wait()
logger.error("after connection")
try connection.authenticate(username: "<username>",
database: "<db>",
password: "<password>").wait()
let syncCodableNIOLambda: SyncCodableNIOLambda<Event, Response> = { (event, context) throws -> EventLoopFuture<Response> in
let future = connection.query(event.query).map { (rows) -> Response in
return Response(value: "\(rows)")
}
return future
}
let sprinter = try SprinterNIO()
//Note amend this line in case if it's required to use a different lambda handler.
sprinter.register(handler: "query", lambda: syncCodableNIOLambda)
try sprinter.run()
} catch {
logger.error("\(String(describing: error))")
}
Note I used Redis with AWS RDS
Requirements:
The lambda must be attached to the VPC configured for Elastic Cache
https://github.com/Andrea-Scuderi/aws-lambda-swift-sprinter/tree/feature/PostgreSQLDemo
This is great help indeed. Thanks
Added examples for Redis #32 and PostgreSQL #33
I am using this example aws server-less environment.
I am able to deploy the code with given example on aws lambda. Now to use this in our actual project I need to use postgres and redis with swift.
I am unable to find example where i can use standalone postgresql with server-side swift without using other server framework like Vapor.
Can you please help us in finding the right-way to integrate swift example with postgres and redis.
Thank you.