Serverless: AWS Lambda and Spring Cloud Function with the Twitter API
Write a Spring Cloud Function that updates a Twitter profile name with the live follower count, package it, and run it on AWS Lambda.
Archive note I wrote this in 2020 on my old blog. It moved here in 2026 with the code and diagrams redone; library versions and APIs may have changed since. Original post.
Contents
In this article we’ll build a simple AWS Lambda function with Spring Cloud Function that updates a Twitter profile name automatically. We’ll cover:
- the Twitter API,
- Spring Cloud Function with Spring Boot, and
- deploying it as a serverless AWS Lambda function.
The Twitter API
Twitter’s API is one of the most popular around: you can search tweets, pull data and analyse trends for a location, among other things. To use it, go to developer.twitter.com/apps and create an app, describing what it’s for. You’ll get four keys: an API key, an API secret key, an access token and an access token secret.
To keep things simple, our function will update my Twitter profile name, appending the account’s current follower count:
Spring Cloud Function
Spring Cloud Function is a project that promotes writing business logic as plain functions. The same code can then run as a web endpoint, a stream processor or a task, and it works well with serverless platforms. A traditional Spring Boot REST API runs in an embedded server on a port; a Spring Cloud Function isn’t tied to any server, so a platform such as AWS Lambda can run it on demand.
Create a Spring Boot starter project and add these dependencies. We’ll use the Twitter4J client to talk to the Twitter API.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
<version>4.0.7</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>This doesn’t include an embedded server for testing locally. If you want to run the application on a port and test it, add this dependency too:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
</dependency>Next, we create a Twitter client with the keys we got earlier. The keys live in a properties file and are injected. Don’t publish these keys anywhere, or your Twitter account is a goner.
@Component
public class TwitterConfig {
@Autowired
private Environment env;
public Twitter getTwitterInstance() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(env.getProperty("twitter.api.key"))
.setOAuthConsumerSecret(env.getProperty("twitter.api.secret"))
.setOAuthAccessToken(env.getProperty("twitter.api.accessToken"))
.setOAuthAccessTokenSecret(env.getProperty("twitter.api.accessSecret"));
TwitterFactory tf = new TwitterFactory(cb.build());
return tf.getInstance();
}
}Next, the service that updates the profile name. It appends the current follower count to the existing name, and returns the new name.
@Service
public class TwitterService {
@Autowired
TwitterConfig twitterConfig;
public String updateUsername() {
Twitter twitter = twitterConfig.getTwitterInstance();
User user;
try {
user = twitter.showUser(twitter.getId());
User updatedProfile = twitter.updateProfile(
user.getName() + " | " + user.getFollowersCount(), null, null, null);
return updatedProfile.getName();
} catch (TwitterException e) {}
return null;
}
}Because it appends to the current name, running it twice gives “Shahul | 694 | 695”. To run it on a schedule, strip any old count first. It’s also worth logging the TwitterException rather than swallowing it.
All that’s left is to expose the service. Normally a controller would do that. In Spring Cloud Function, we expose it as a bean of one of Java’s functional interfaces: Supplier, Function or Consumer. Custom functional interfaces need a wrapper, which is beyond the scope of this article.
Here we return a Supplier<String> that supplies the updated profile name. When the web starter is on the classpath, Spring Cloud Function also exposes it as a REST endpoint at /username.
@SpringBootApplication
public class SpringCloudAwsLambdaApplication {
@Autowired
TwitterService service;
public static void main(String[] args) {
SpringApplication.run(SpringCloudAwsLambdaApplication.class, args);
}
@Bean
public Supplier<String> username() {
return () -> service.updateUsername();
}
}Finally, to deploy to AWS Lambda we need a handler class, so that Lambda knows how to invoke the application and what the function’s input and output types are. We extend SpringBootRequestHandler with String for both, because the function returns a String. It takes no input in this case, but the input type still has to be declared.
public class TwitterHandler extends SpringBootRequestHandler<String, String> {}Here’s how the pieces fit together when Lambda runs the function:
Run a Maven build to create the jar we’ll upload.
Serverless with AWS Lambda
Serverless doesn’t mean there’s no server. It means you, the developer, don’t have to set one up or look after it. You write the business logic, as we’ve done, and hand it to a serverless provider to run.
The main advantages:
- no servers to manage, and
- you pay only for the time your function runs.
AWS Lambda is Amazon’s service for running and managing serverless functions.
Step 1: create the function
Sign in to the AWS console (you’ll need an account with a credit card on file), search for Lambda, and choose Create function. Pick Author from scratch and fill in:
| Setting | Value |
|---|---|
| Function name | TwitterUpdate |
| Runtime | Java 8 (in 2020; use Java 21 today) |
| Permissions | the default execution role, which can write logs to CloudWatch |
You could equally upload a Node.js or Python function here. Choose Create function.
Step 2: point Lambda at the handler
Under Edit basic settings, set:
| Setting | Value |
|---|---|
| Handler | com.shahul.serverless.TwitterHandler |
| Memory | 512 MB |
| Timeout | 30 seconds |
and save.
Step 3: upload the jar
In the Function code section, choose Actions → Upload a .zip or .jar file, and upload the jar from the Maven build.
Step 4: configure a test event
Next to the Test button, configure a test event. If the function took input, this is where you’d provide it. Ours doesn’t, so the event is just an empty string:
""Step 5: run it
Choose Test. The execution succeeds, the function returns the new profile name, and the Twitter profile updates:
"Shahul | 694"| Duration | Billed duration | Memory configured | Max memory used | Init duration |
|---|---|---|---|---|
| 15,492.56 ms | 15,500 ms | 512 MB | 162 MB | 470.11 ms |
START RequestId: dc43e665-3d68-4496-9c6b-638c5f258fc3 Version: $LATEST
07:34:15.582 [main] INFO org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer - Initializing: class com.shahul.serverless.SpringCloudAwsLambdaApplicationMost of those 15 seconds are cold-start work. As the log shows, the adapter builds the whole Spring application context inside the first invocation, on the modest CPU share a 512 MB function gets, and only then calls Twitter. Later invocations of a warm function reuse the context and are much faster.
That’s it: our first serverless AWS Lambda function with Spring Cloud Function.
Improving the function
- Call it from outside. Put Amazon API Gateway in front of the function so it can be called as a REST API. Be careful: some of these services are billed.
- Run it on a schedule. Trigger the function every 30 minutes with an Amazon EventBridge schedule (a cron job), so the follower count on the profile stays up to date. You could also change the profile picture every day of the week, as a fun experiment. The possibilities are endless, and there’s plenty of data analysis you could do too.
Conclusion
This is a getting-started guide, and there’s a lot more to explore.
The project is on GitHub: shahulbasha/serverlessawslambda.