https://swapi.co/
{
"name": "Luke Skywalker",
"height": "1.72 m",
"mass": "77 Kg",
"hair_color": "Blond",
"skin_color": "Caucasian",
"eye_color": "Blue",
"birth_year": "19 BBY",
"gender": "Male",
"homeworld": "http://swapi.co/api/planets/1/",
"films": [
"http://swapi.co/api/films/1/",
"http://swapi.co/api/films/2/",
"http://swapi.co/api/films/3/"
],
"species": [
"http://swapi.co/api/species/1/"
],
"vehicles": [
"http://swapi.co/api/vehicles/14/",
"http://swapi.co/api/vehicles/30/"
],
"starships": [
"http://swapi.co/api/starships/12/",
"http://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-10T13:52:43.172000Z",
"url": "http://swapi.co/api/people/1/"
}
App #1
App #2
App #3
App #4
App #1
App #2
App #3
App #4
GraphQL
Your application code
Database
Internal APIs
Remote APIs
Type definitions
Server publishes possibilities
Client specifies concrete data requirements
Serverless architectures refer to applications that significantly depend on third-party services (knows as Backend as a Service or "BaaS") or on custom code that's run in ephemeral containers (Function as a Service or "FaaS"), the best known vendor host of which currently is AWS Lambda. By using these …
Mike Roberts
https://martinfowler.com/articles/serverless.html
Function as a unit of application logic
* (somewhat)
YES! 🙃
Machines in
Datacenters
Virtualization
in the Cloud
Containers
in the Cloud
Serverless
in the Cloud
Some limitations prevent certain use cases.
var params = {
Code: {},
Description: "",
FunctionName: "MyFunction",
Handler: "souce_file.handler_name",
MemorySize: 128,
Publish: true,
Role: "arn:aws:iam::123456789012:role/service-role/role-name",
Runtime: "nodejs4.3",
Timeout: 15,
VpcConfig: {}
};
lambda.createFunction(params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "The AWS CloudFormation template for this Serverless application",
"Resources": {
"ServerlessDeploymentBucket": {
"Type": "AWS::S3::Bucket"
},
"IamRoleLambdaExecution": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"RoleName": {
"Fn::Join": [
"-",
[
"serverless-simple-http-endpoint",
"dev",
"us-east-1",
"lambdaRole"
]
]
}
}
},
"IamPolicyLambdaExecution": {
"Type": "AWS::IAM::Policy",
"DependsOn": [
"IamRoleLambdaExecution"
],
"Properties": {
"PolicyName": {
"Fn::Join": [
"-",
[
"dev",
"serverless-simple-http-endpoint",
"lambda"
]
]
},
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream"
],
"Resource": "arn:aws:logs:us-east-1:*:*"
},
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:*:*"
}
]
},
"Roles": [
{
"Ref": "IamRoleLambdaExecution"
}
]
}
},
"CurrentTimeLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "ServerlessDeploymentBucket"
},
"S3Key": "serverless/serverless-simple-http-endpoint/dev/1484930732222-2017-01-20T16:45:32.222Z/serverless-simple-http-endpoint.zip"
},
"FunctionName": "serverless-simple-http-endpoint-dev-currentTime",
"Handler": "handler.endpoint",
"MemorySize": 1024,
"Role": {
"Fn::GetAtt": [
"IamRoleLambdaExecution",
"Arn"
]
},
"Runtime": "nodejs4.3",
"Timeout": 6
},
"DependsOn": [
"IamPolicyLambdaExecution",
"IamRoleLambdaExecution"
]
},
"CurrentTimeLambdaVersionZ1TELpJKRofoApVATkwyg3d6mnjiRs3VIERorWczoY": {
"Type": "AWS::Lambda::Version",
"DeletionPolicy": "Retain",
"Properties": {
"FunctionName": {
"Ref": "CurrentTimeLambdaFunction"
},
"CodeSha256": "Z1TELpJKRofoApVATkwyg3d6mnjiRs3VIERorW/czoY="
}
},
"ApiGatewayRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "dev-serverless-simple-http-endpoint"
}
},
"ApiGatewayResourcePing": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"ParentId": {
"Fn::GetAtt": [
"ApiGatewayRestApi",
"RootResourceId"
]
},
"PathPart": "ping",
"RestApiId": {
"Ref": "ApiGatewayRestApi"
}
}
},
"Roles": [
{
"Ref": "IamRoleLambdaExecution"
}
]
}
},
"CurrentTimeLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "ServerlessDeploymentBucket"
},
"S3Key": "serverless/serverless-simple-http-endpoint/dev/1484930732222-2017-01-20T16:45:32.222Z/serverless-simple-http-endpoint.zip"
},
"FunctionName": "serverless-simple-http-endpoint-dev-currentTime",
"Handler": "handler.endpoint",
"MemorySize": 1024,
"Role": {
"Fn::GetAtt": [
"IamRoleLambdaExecution",
"Arn"
]
},
"Runtime": "nodejs4.3",
"Timeout": 6
},
"DependsOn": [
"IamPolicyLambdaExecution",
"IamRoleLambdaExecution"
]
},
"CurrentTimeLambdaVersionZ1TELpJKRofoApVATkwyg3d6mnjiRs3VIERorWczoY": {
"Type": "AWS::Lambda::Version",
"DeletionPolicy": "Retain",
"Properties": {
"FunctionName": {
"Ref": "CurrentTimeLambdaFunction"
},
"CodeSha256": "Z1TELpJKRofoApVATkwyg3d6mnjiRs3VIERorW/czoY="
}
},
"ApiGatewayRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "dev-serverless-simple-http-endpoint"
}
},
"ApiGatewayResourcePing": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"ParentId": {
"Fn::GetAtt": [
"ApiGatewayRestApi",
"RootResourceId"
]
},
"PathPart": "ping",
"RestApiId": {
"Ref": "ApiGatewayRestApi"
}
}
},
"ApiGatewayMethodPingGet": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"HttpMethod": "GET",
"RequestParameters": {},
"ResourceId": {
"Ref": "ApiGatewayResourcePing"
},
"RestApiId": {
"Ref": "ApiGatewayRestApi"
},
"AuthorizationType": "NONE",
"Integration": {
"IntegrationHttpMethod": "POST",
"Type": "AWS_PROXY",
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": [
"CurrentTimeLambdaFunction",
"Arn"
]
},
"/invocations"
]
]
}
},
"MethodResponses": []
}
},
"ApiGatewayDeployment1484930732234": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "ApiGatewayRestApi"
},
"StageName": "dev"
},
"DependsOn": [
"ApiGatewayMethodPingGet"
]
},
"CurrentTimeLambdaPermissionApiGateway": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"CurrentTimeLambdaFunction",
"Arn"
]
},
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:execute-api:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
{
"Ref": "ApiGatewayRestApi"
},
"/*/*"
]
]
}
}
}
},
"Outputs": {
"ServerlessDeploymentBucketName": {
"Value": {
"Ref": "ServerlessDeploymentBucket"
}
},
"CurrentTimeLambdaFunctionArn": {
"Description": "Lambda function info",
"Value": {
"Fn::GetAtt": [
"CurrentTimeLambdaFunction",
"Arn"
]
}
},
"CurrentTimeLambdaFunctionQualifiedArn": {
"Description": "Current Lambda function version",
"Value": {
"Ref": "CurrentTimeLambdaVersionZ1TELpJKRofoApVATkwyg3d6mnjiRs3VIERorWczoY"
}
},
"ServiceEndpoint": {
"Description": "URL of the service endpoint",
"Value": {
"Fn::Join": [
"",
[
"https://",
{
"Ref": "ApiGatewayRestApi"
},
".execute-api.us-east-1.amazonaws.com/dev"
]
]
}
}
}
}
# serverless.yml
service: serverless-simple-http-endpoint
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs4.3
functions:
currentTime:
handler: handler.endpoint
events:
- http:
path: ping
method: get
// handler.js
module.exports.endpoint = (event, context, callback) => {
const time = new Date().toTimeString();
const response = {
statusCode: 200,
body: JSON.stringify({
message: `Hello, the current time is ${time}.`,
}),
};
callback(null, response);
};
import {
GraphQLObjectType,
GraphQLString,
} from 'graphql';
const MeetupType = new GraphQLObjectType({
name: 'Meetup',
description: 'A gathering of people',
fields: () => ({
name: {
type: GraphQLString,
description: 'The name of the meetup',
},
description: {
type: GraphQLString,
description: 'The long description of the meetup',
},
}),
});
export default MeetupType;
// schema.js
const QueryType = new GraphQLObjectType({
name: 'Query',
fields: () => ({
meetups: {
type: new GraphQLList(MeetupType),
resolve: () => endpoints.getMeetups(),
}
}),
});
export default new GraphQLSchema({
query: QueryType,
});
// handler.js
const handle = require('./schema');
module.exports.graphql = (event, context, callback) => {
handle(event.body.query, event.body.variables)
.then((response) => callback(null, response))
.catch((error) => callback(error));
};
// getMeetups.js
import fetch from 'node-fetch';
const url = 'https://api.meetup.com/viennajs/events?photo-host=secure
&sig_id=12607916&sig=d06a49439dafad0b17b5a275f882cc1f79711430';
export default () => fetch(url).then((res) => res.json());
https://github.com/serverless/serverless-graphql-apollo
https://github.com/serverless/serverless-graphql-relay